【数据结构】单链表--基础
来源:互联网 发布:男士去黑头洗面奶 知乎 编辑:程序博客网 时间:2024/06/13 22:23
单链表的几个基本问题:
1.比较顺序表和链表的优缺点,说说它们分别在什么场景下使用?
顺序表(物理位置相邻):优点:在一段内存中用数组连续存放,所以方便随机查找元素。
缺点:动态开辟,容易造成内存浪费,需要一个元素,开辟过多。前面添加元素时,要逐个挪动后面的每个元素,较麻烦。
场景:数据频繁查找修改,但很少添加。
单链表(物理位置不相邻):优点:方便开辟,用多少开辟多少,不会造成内存空间浪费。
缺点:不方便直接查找。
场景:频繁添加数据,但很少查询。
2.从尾到头打印单链表 :
可以运用递归的方法从尾到头打印。
从头节点向后递归,结束条件当节点为空
返回输出该节点的值。
void PrintTailToHead(ListNode *pList) //逆序打印 用递归{if (pList == NULL)return;PrintTailToHead(pList->next);//子问题printf("%d->", pList->data);}
3.删除一个无头单链表的非尾节点 :
1.将后面节点的值赋给pos
2.删除pos
void EraseNonTail(ListNode *pos) //无头删除指定非尾节点{assert(pos);ListNode *cur = pos->next;//1.交换与后面的值DataType tmp = cur->data;cur->data = pos->data;pos->data = tmp;//2.删除后面的节点pos->next = cur->next;free(cur);}
4.在无头单链表的一个节点前插入一个节点:
1.在pos后面插入一节点
2.将pos与后面的值交换
void InsertNonFront(ListNode *pos, DataType x) //在无头单链表的一个节点前插入一个节点{assert(pos);//1.后面插入ListNode *tmp = BuyNode(x);tmp->next = pos->next;pos->next = tmp;//2.值交换DataType n = pos->data;pos->data = tmp->data;tmp->data = n;}
5.单链表实现约瑟夫环 :
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
俩个循环 里循环走数k个,将第k个删除。外循环从删除后下一个再开始直到剩下一个节点。
ListNode* JoseohRing(ListNode *pList, int k)//约瑟夫环{if (pList == NULL)return NULL;ListNode *cur = pList;while (cur->next != cur){int count = k;while (--count) //走k-1次{cur = cur->next;}ListNode *next = cur->next;cur->data = next->data;cur->next = next->next;free(next);}return cur;}
6.逆置/反转单链表
ListNode* Reverse(ListNode *pList)//链表的逆置{if ((pList == NULL) || (pList->next == NULL))return pList;else{ListNode *newHead = NULL;ListNode *cur = pList;while (cur){ListNode *tmp = cur;cur = cur->next;tmp->next = newHead;newHead = tmp;}return newHead;}}
7.单链表排序(冒泡排序|快速排序)
void BubbleSort(ListNode *pList)//冒泡排序{if ((pList == NULL) || (pList->next == NULL))return;else{ListNode *tail = NULL;while (tail != pList->next){int exchange = 0;ListNode *cur = pList;ListNode *next = cur->next;while (next != tail){if (cur->data > next->data){DataType tmp = cur->data;cur->data = next->data;next->data = tmp;exchange = 1;}next = next->next;cur = cur->next;}if (exchange == 0)return;tail = cur;}}}
8.合并两个有序链表,合并后依然有序
ListNode* MergeList(ListNode *pList1, ListNode *pList2)//归并排序{if (pList1 == NULL)return pList2;else if (pList2 == NULL)return pList1;else{//摘做头ListNode *list = NULL;if (pList2->data < pList1->data){list = pList2;pList2 = pList2->next;}else{list = pList1;pList1 = pList1->next;}ListNode *tail = list;while (pList1 && pList2){if (pList1->data < pList2->data){tail->next = pList1;pList1 = pList1->next;}else{tail->next = pList2;pList2 = pList2->next;}tail = tail->next;}if (pList1)tail->next = pList1;elsetail->next = pList2;return list;}}
9.查找单链表的中间节点,要求只能遍历一次链表
定义 fast 与 slow fast每走2个slow走一个 fast走完全部,slow走了一半 为中节点
ListNode* FindMidNode(ListNode *pList)//查找单链表的中间节点{ListNode *fast = pList;ListNode *slow = pList;ListNode *prev = pList;while ((fast)&&(fast->next)){fast = fast->next;fast = fast->next;prev = slow;slow = slow->next;}if (fast == NULL)slow = prev;return slow;}
10.查找单链表的倒数第k个节点,要求只能遍历一次链表
将fast先走k-1 然后与slow同时走 fast走动尾节点时,slow为倒数第k节点
//k<=链表个数ListNode* FindTailkNode(ListNode *pList, DataType k)//查找单链表的倒数第k个节点{if (pList == NULL)return NULL;ListNode *fast = pList;ListNode *slow = pList;while (--k){fast = fast->next;}while (fast->next){fast = fast->next;slow = slow->next;}return slow;}
阅读全文
2 0
- 数据结构基础之单链表
- 数据结构基础之单链表
- 数据结构基础--单链表
- 【数据结构】单链表--基础
- 数据结构基础【03】单链表
- 数据结构基础--单链表逆序
- 基础数据结构——单链表
- 第十三章 数据结构基础--单链表
- 数据结构基础
- 数据结构基础
- 数据结构基础
- 数据结构基础
- 数据结构基础
- 基础数据结构
- 数据结构基础
- 数据结构基础
- 数据结构基础
- 数据结构基础
- UTF-8、UTF-16、UTF-32的区别
- 理解ROS服务和参数(七)
- 线程
- rabbitmq整合spring
- #pragma pack用法笔记
- 【数据结构】单链表--基础
- Linux运维笔记-文档总结-iSCSI存储服务
- IPC实现机制(四)---信号量(sem)
- “上传图片”问题的解决
- 正则表达式速查表
- JAVA 复习总结(四)
- LIVE555 交叉编译
- javacsv.jar写csv文件时,数字过长会变成科学表达法怎么办
- 提交APPStore广告标识如何填