赞
踩
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- #include <time.h>
- struct Node
- {
- int data;
- struct Node* next;
- };
- //创建有头链表
- struct Node* createList()
- {
- //动态内存申请
- struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
- assert(headNode);
- headNode->next = NULL;
- return headNode;
- }
- //创建节点
- struct Node* createNode(int data)
- {
- struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
- assert(newNode);
- newNode->data = data;
- newNode->next = NULL;
- return newNode;
- }

有序链表的构建过程是怎么样的?以上数据依次插入到链表如何形成有序?需要从原链表中找第一次大于要插入元素的位置,如果没有找到就插在链表的后面 (假设从小到大排序)
- //要插入的链表 要插入的数据
- void push_sort(struct Node* list, int data)
- {
- //把用户的数据变成一个节点
- struct Node* newNode = createNode(data);
- //找第一次大于新节点元素的位置以及前驱节点-> 指定位置插入
- struct Node* preNode = list;
- //当前节点
- struct Node* curNode = list->next;
- //当前节点不为空 并且当前节点的数据 <= 指定数据
- while (curNode != NULL && curNode->data <= data)
- {
- //接着往下找
- preNode = curNode;
- curNode = preNode->next;
- }
- //当前节点为空 preNode == list 代表没有移动一步
- if (curNode == NULL && preNode == list)
- {
- //链表为空直接把新节点插到 list 后面
- list->next = newNode;
- }
- //当前节点为空 preNode != list
- else if (curNode == NULL && preNode != list)
- {
- //没有找到直接放在链表的最后面
- preNode->next = newNode;
- }
- //在中间
- else
- {
- //做插入
- preNode->next = newNode;
- newNode->next = curNode;
- }
- }

法一:
遍历链表,再创建一个链表,采用表头法插入,就实现反转了
法二:
有 3 个指针指向三个位置,只需要改变指针的方向改变即可,最后处理头节点
nextNode:用于保存下一个,断开之前先保存
①把当前节点中的 next 指针指向它的前驱节点
②把 preNode 移到 curNode 的位置,把 curNode 移到 nextNode 的位置,循环重复以上操作,直到最后一个节点
③退出循环时,把 headNode 指向最后一个节点即可
从而实现链表的反转(直接把指针的方向改变)
由于保存了下一个节点,把链表分成多个子链表,一步步把指针反转
每次从原链表中拆一个节点出来把指针反转,重复此操作
①第一个节点的前驱节点等于空
②当前节点等于第一个节点
③当前节点的下一个可以理解为剩下的链表,每次从剩下的链表中拿一个头节点出来,把指针反转,指向前面那个节点,剩下的链表只有一个节点的时候,把 headNode 指向最后一个节点即可
- //要反转的链表
- void reverse(struct Node* list)
- {
- //链表为空或者链表只有一个节点,不需要反转
- if (list == NULL || list->next == NULL|| list->next->next == NULL)
- return;
- //第一个节点的前驱节点等于空
- struct Node* preNode = NULL;
- //当前节点等于第一个节点
- struct Node* curNode = list->next;
- //当前节点的下一个-> 也就是剩下的链表
- //两个节点以上
- //剩下的链表从第3个节点开始
- struct Node* surList = curNode->next;
- //剩下链表不为空
- while (surList != NULL)
- {
- //依次做反转
- //当前节点的next指针指向preNode
- curNode->next = preNode;
- preNode = curNode;
- curNode = surList;
- surList = curNode->next;
- }
- //做最后一步的连接
- curNode->next = preNode;
- list->next = curNode;
- }

- void printList(struct Node* list)
- {
- //定义一个移动的指针从第二个节点开始打印
- struct Node* pmove = list->next;
- //当前节点不为空
- while (pmove != NULL)
- {
- //打印数据
- printf("%d\t", pmove->data);
- //移到下一个位置
- pmove = pmove->next;
- }
- printf("\n");
- }
两个有序链表 1 3 5、2 4 6 做归并,把第二个链表遍历一遍,做一次有序插入
- //把第一个链表中的值归并到第二个链表中
- void mergeList(struct Node* list1, struct Node* list2)
- {
- //循环遍历第二个链表
- struct Node* pmove = list2->next;
- //节点不为空
- while (pmove != NULL)
- {
- //插到list1中 要插入的数据
- push_sort(list1, pmove->data);
- pmove = pmove->next;
- }
- }
- int main()
- {
- srand((unsigned int)time(NULL));
- struct Node* list = createList();
- //插入
- for (int i = 0; i < 10; i++)
- {
- push_sort(list, rand() % 100);
- }
- printList(list);
- reverse(list);
- printList(list);
-
- //创建两个链表
- struct Node* list1=createList();
- push_sort(list1, 1);
- push_sort(list1, 3);
- push_sort(list1, 5);
- struct Node* list2 = createList();
- push_sort(list2, 2);
- push_sort(list2, 4);
- push_sort(list2, 6);
- mergeList(list1, list2);
- printList(list1);
- return 0;
- }
-
- /* 输出 */
-
- 16 29 42 55 61 64 75 79 83 96
- 96 83 79 75 64 61 55 42 29 16
- 1 2 3 4 5 6

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。