Partition List(链表的插入和删除操作,找前驱节点)

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.

You should preserve the original relative order of the nodes in each of the two partitions.

For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.

思路:

1.由于不能改变原来的相对位置,所以直接置换值是不行的。

2.其实这个题类似于快速排序的Partition函数,该思路是,随机从数组中选取一个值作为参考值,使得数组中比该参考值小的数字排在参考值左端,数组中比该参考值大的数字排在参考值右端。

遍历所有节点,发现比x小的节点就”交换“,交换的过程即先删除那个节点,然后插入到对应位置。

这里有一个前提,即若第一个数就小于x的话,是不需要“交换的”。

另外一点需要注意的是:删除链表某个节点之后,指针p的值可能出现不定义状态,故在删除之前,先让p指向要删除节点的下一个节点。

 class Solution {
 public:
     //删除链表中位置为loc的节点,从1开始
     int Delete(ListNode* &head,int loc){
         ListNode* p=NULL;
         ListNode* q=NULL;
         p=head;
         int i=1;
         //找到前驱节点
         while(i<loc-1&&p->next){
             ++i;
             p=p->next;
         }
         q=p->next;
         p->next=q->next;

         int val=q->val;
         free(q);
         return val;
     }
     ListNode* Insert(ListNode* &head,int loc,int val){
         ListNode* p=head;
         p=head;
         int i=1;
         if(loc==1){
             ListNode* s=(ListNode*)malloc(sizeof(ListNode));
             s->val=val;
             s->next=p;
             return s;
         }
         //找到前驱节点
         while(i<loc-1&&p->next){
             ++i;
             p=p->next;
         }
         ListNode* s=(ListNode*)malloc(sizeof(ListNode));
         s->val=val;
         s->next=p->next;
         p->next=s;
         return head;
     }
     ListNode *partition(ListNode *head, int x) {
         if(head==NULL) return NULL;
         int insertloc=0;
         int loc=0;
         ListNode* p=head;
         while(p!=NULL)
         {
             ++loc;
             if(p->val<x)
             {
                 ++insertloc;
                 if(insertloc!=loc){
                     p=p->next;
                     int val=Delete(head,loc);
                     head=Insert(head,insertloc,val);
                     continue;
                 }
             }
             p=p->next;
         }
         return head;
     }
 };
时间: 2024-10-06 16:26:18

Partition List(链表的插入和删除操作,找前驱节点)的相关文章

单链表实现“插入”和“删除”操作

在单链表中,又如何实现"插入"和"删除"操作呢? 插入操作: 假设我们要在线性表的两个数据元素a和b之间插入一个数据元素x,已知p为其单链表存储结构中指向结点a的指针.为插入数据元素x,首先要生成一个数据域为x的结点,然后插入在单链表中.根据插入操作的逻辑定义,还需修改结点a中的指针域,令其指向结点x,而结点x中的指针域应该指向b结点,从而实现3个元素a,b和x之间逻辑关系的变化. 假设s为指向结点x的指针.则上述指针修改用语句描述即为: s->next=p-

数据结构Java实现03----单向链表的插入和删除

数据结构Java实现03----单向链表的插入和删除 文本主要内容: 链表结构 单链表代码实现 单链表的效率分析 一.链表结构:            概念: 链式存储结构是基于指针实现的.我们把一个数据元素和一个指针称为结点.   数据域:存数数据元素信息的域. 指针域:存储直接后继位置的域. 链式存储结构是用指针把相互直接关联的结点(即直接前驱结点或直接后继结点)链接起来.链式存储结构的线性表称为链表. 链表类型: 根据链表的构造方式的不同可以分为: 单向链表 单向循环链表 双向循环链表 二

二叉平衡树的插入和删除操作

1.      二叉平衡树 二叉排序树的时间复杂度和树的深度n有关.当先后插入的结点按关键字有序时,二叉排序树退化为单枝树,平均查找长度为(n+1)/2,查找效率比较低.提高查找效率,关键在于最大限度地降低树的深度n.因此需要在构成二叉排序树的过程中进行“平衡化”处理,使之成为二叉平衡树. 二叉平衡树,又称AVL树.它或者是一棵空树,或者是具有下列性质的树: 1)      具备二叉排序树的所有性质: 2)      左子树和右子树深度差的绝对值不超过1: 3)      左子树和右子树都是二叉

面试之路(10)-BAT面试之java实现单链表的插入和删除

链表的结构: 链表在空间是不连续的,包括: 数据域(用于存储数据) 指针域(用于存储下一个node的指针) 单项链表的代码实现: 节点类 构造函数 数据域的get,set方法 指针域的get,set方法 代码: public class Node { Object element; //数据域 Node next; //指针域 //构造方法 public Node(Object obj, Node nextval) { this.element = obj; this.next = nextva

二叉查找树(二叉排序树)创建,插入,删除操作。

二叉排序树 二叉排序树是一个基础的树的数据结构.应用非常多. 它的特性就是,左孩子小于parent,右孩子大于parent. 寻找节点 寻找节点就是直接根据数值的大小,从root节点开始遍历,大于当前遍历节点就向它的右子树查找,相反则查找它的左子树.然后返回. 查找最大最小节点 直接根据root节点,遍历到最右就是最大节点,遍历到最左,就是最小节点. 插入节点 插入节点我这里插入的节点都会成为叶子节点.根据大小的关系向下遍历,遍历到最后的节点,然后插入就可以了. 删除节点 这里删除节点是相对麻烦

单链表 - 插入和删除操作

下图展示了单链表的基本结构: head指针是链表的头指针,指向第一个节点,每个节点的next指针域指向下一个节点,最后一个节点的next指针域为NULL,在图中用0表示. 下面先来看程序(栈的链式存储实现,另外一个实现点这里)和对应的输出(注意输出前进行了链表反转(见<单链表反转>,否则程序后面的while循环输出的顺序是250,200,100),接着来分析程序: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

闭散列表的查找、插入和删除操作的完整C代码

/*闭散列表的建立.查找.插入.删除*/ #include <stdio.h> #define NIL -1 //假设关键字为非负整数 #define DEL -2 typedef int KeyType; KeyType HashTable[13]; //便于验证算法,关键字个数假定为不超过13,哈希表长定为13 //关键字插入函数 void InsertHashTable(KeyType k) { for(int i=0; i<13; i++) if( NIL == HashTabl

简直offer之链表的插入和删除

在插入和删除链表的时候一定要注意不要让链表断了,另外要特别注意对头结点的单独考虑 参考剑指offer上第50页删除给定值的结点的代码.得知,要删除一个节点必须知道该节点的前一个节点.书上的代码使用pNode.next 和pNode.next.value来判断的 下面把代码附上,有个问题 public static ListNode deleteNode(ListNode head,int value){ if(head==null){ return null; } ListNode toBeDe

链表的插入、删除

结构体: 1 typedef struct Student{ 2 int m_val; 3 struct Student* m_next; 4 }NODE,*pNODE; 链表的插入: 1 //尾部插入 2 void linkInitTail(pNODE* pphead) 3 { 4 int val; 5 pNODE pNew,pTail; 6 while(scanf("%d",&val) == 1) 7 { 8 pNew = (pNODE)calloc(1,sizeof(NO