while(x != 9999){ LNode * s = (LNode *)malloc(sizeof(LNode)); s -> data = x; s -> next = NULL; // 是第一个结点 if(!list) list = s; else{ // 平常的尾插 s -> next = r -> next; r -> next = s; } r = s; cin >> x; } }
删除带头结点的单链表中所有值为 x 的结点
核心思想
板子
核心代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// 删除带头结点单链表中 x 的值 voidDel_x(LinkList & list, int x){ LNode * pre = list, * cur = list -> next;
while(cur){ // 当前结点是应该被删除的结点 if(cur -> data == x){ LNode * q = cur; cur = cur -> next; pre -> next = cur; free(q); }else{ // 当前结点不是应该被删除的结点 pre = cur; cur = cur -> next; } } }
// 假设最小值是第一个节点 LNode * t = cur; // 打擂台 while(cur){ // 如果发现比最小值还要小的 // 打赢了,新的当 t if(cur -> data < t -> data){ t = cur; // pre 作为 新的min_pre min_pre = pre; } // 俩指针后移 pre = cur; cur = cur -> next; }
// 将原单链表A分裂为:`奇A表`和`偶B表` LinkList Re_Create(LinkList & A){ // 准备B表 LinkList B = (LNode *)malloc(sizeof(LNode)); B -> next = NULL;
// 准备工作 LNode * ra = A , * rb = B; // A 和 B 的尾指针 LNode * p = A -> next; // 遍历准备工作
// A 表断开 A -> next = NULL;
// 奇偶序列计数 int i = 0; while(p){ i++; // 奇 if(i % 2){ ra -> next = p; ra = p; }else{ // 偶 rb -> next = p; rb = p; } p = p -> next; } // 尾指针置空 ra -> next = NULL; rb -> next = NULL;
voidrearrangedList(ListNode* head){ if(!head->next) return; // 获取链表的长度 int len = 0; for(auto p = head ; p ; p = p -> next) len++;
// 链表中间的结点 int left = (len + 1) >> 1; auto a = head; for(int i = 0 ; i < left - 1 ; i++) a = a -> next; // 反转后半段链表,b在前,c在后 auto b = a -> next , c = b -> next; // a->next 是为了从中间将链表截断;b->next 是因为此时的 b 是反转后链表的结尾元素 a -> next = b -> next = NULL;
while(c){ auto p = c -> next; c -> next = b; b = c; c = p; }
// 合并链表,注意此时 b 指向反转链表头部 auto p = head; auto q = b; // o -> o -> o -> NULL (p) // o -> o -> o -> NULL (q) while(q){ auto o = q -> next; q -> next = p -> next; p -> next = q; p = q -> next; q = o; } }