链表问题
来源:互联网 发布:网络诈骗 运营商 编辑:程序博客网 时间:2024/05/16 06:27
关于链表插入和删除的注意事项:
1.特殊处理链表为空和链表长度为1的情况。
2.注意插入操作调整的过程
3.注意头尾节点需要特殊考虑
给定一个整数num,在有序环形链表中插入一个节点值为num的节点,并且保证这个环形单链表依然有序。
采用两个节点指针,判断何种情况需要在两个指针之间插入节点。如果两个指针转了一圈都没有发现要插入的位置,则插在头结点前
给定一个链表的头结点head,在给定一个数num,把链表调整成节点值小于num的节点都放在链表值等于num的放在链表的中间,链表值大于num的节点放在链表的右边
方法一:
1.将链表的所有节点都放在数组中,然后将数组进行快排划分调整过程。
2.将数组重新连成链表
方法二:
分别将小于部分,等于部分,大于部分形成三个小链表,再将三个小链表连成大链表
给定两个有序链表的头结点,h1和h2打印两个有序链表的公共部分。
如有有一个为空,直接返回
否则,分别从两个链表的头结点遍历,如果n1
设计一个单链表函数,给定一个链表的头节点,使每k个节点之间逆序,如果最后不够k个节点,则不调整。
方法一:
利用栈进行处理,元素依次进栈,进够k个就依次弹出,如果最后不足k个则不要逆序
方法二:
记录下每组节点的头节点,每收集k个元素进行逆序调整,
给定一个单链表的头结点,再给定一个val,把所有等于val的节点删掉
可以看最构造新链表的过程。
一个链表中,每个节点不仅含有一条指向下一个节点额next指针,同时含有一条rand指针,rand指针可能指向任何一个链表中的节点,请复制这种含有rand指针节点的链表。
把每一个节点的拷贝节点放到原节点的后面。
1.单链表的创建、测长、节点查找、删除、插入、打印、反转
链表的反转
为了反转这个单链表,我们先让头结点的next域指向结点2,再让结点1的next域指向结点3,最后将结点2的next域指向结点1,就完成了第一次交换,顺序就变成了Header-结点2-结点1-结点3-结点4-NULL,然后进行相同的交换将结点3移动到结点2的前面,然后再将结点4移动到结点3的前面就完成了反转,思路有了,就该写代码了:
//将1,2节点交换,//head ->next = node2;//node1 ->next = node2->next;//node2 ->next = node1;Node *Reverse_List(Node *head){ Node *rev_head = NULL; Node *pNode = pHead; Node *pPrev = NULL; while(pNode != NULL){ Node *pNext = pNode ->next; if(pNode) rev_head = pNode; pNode ->next = pPrev; pPrev = pNode; pNode = pNext; } return rev_head;}
2.双向链表的创建、测长、节点查找、删除、插入、打印、反转
3.不使用缓冲区移除链表中重复的节点
4.编写算法找出单链表中倒数第k个节点
利用快指针慢指针来实现:
两个指针指向头节点,快指针先向前走k-1步,然后两个指针再一起移动,最后快指针到达链表末尾的时候慢指针指向倒数第k个节点。
void FindKthtoTail(Node *head, int k ){ if(NULL == head || 0 == k) return; Node * quick = head; Node* slow =NULL; for(size_t i = 0; i< k-1 ;++i){ //快指针先走k-1步 if(quick ->next ){ quick = quick->next ; } slow = head; while(quick ->next){ //快慢指针同时前进 quick = quick-<next; slow = slow->next; } cout<<slow->data<<endl; return ; }
5.删除单链表中某个节点,且只能访问该节点
6.以给定值x为基准,将链表分割成两部分,所有小于x的节点排在x之前
7.两个链表表示两个整数,每个节点表示整数的一位,数位反向(正向)存放,以链表的形式返回两个数的和——大整数问题
8.编写一个方法,传入一个有环链表,返回环路的头结点。如果无环则返回NULL
利用hash表来实现,遍历每个节点,直到出现一个重复出现的节点
方法二:利用快指针、慢指针:若有环,则两个指针会在链表中的某个位置相遇,此时快指针从头重新遍历,当再次相遇的时候,就都指向环头。
9.编写一个方法,判断链表是否是回文串
10.寻找单链表中的中间元素
11.单链表的正向排序
12.判断链表是否存在环
13.有序单链表的合并
Node *Merge(Node *head1,Node *head2){ if(head1 == NULL) return head2; else if(head2 == NULL) return head1; Node *merged_head = NULL; if(head1->data < head2->data){ merged_head = head1; merged_head - >next =Merge(head1->,head2) } else { merged_head = head2; merge_head ->next = Merge(head1,head2->next); } return merged_head;}
14.约瑟夫环问题
15.有序双向循环链表的插入
16.删除两个双向循环链表的相同节点
17.反向打印链表
利用栈、递归来实现
void Reverse_PrintList(Node *head){ stack<Node*> nodes; Node *pNode = head; while(pNode != NULL){ nodes.push(pNode); pNode = pNode->next; } while(!nodes.empty()){ pNode = nodes.top(); nodes.pop(); cout<< pNode -> data<<endl; }}//利用递归来实现void reverse_PrintList(Node *head){ if(head){ reverse_PrintList(head->next); cout<<head->data<<endl; } return ;}
18.单链表反转的递归实现
19.复杂链表的复制
20.求两个链表的第一个公共子节点
两个链表从后到前寻找,找到最后一个相同的节点就是两个链表的第一个公共子节点,使用两个辅助栈。
Tips:该题在逆时针旋转90度之后编程寻找最低公共祖先的问题。
21.二叉搜索树和双向链表:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表,不能创建任何新节点,只能调整树中节点指针的指向。
解法:中序遍历的过程中,将前驱和后继连接起来
void change(Node *p, Node *&last) //中序遍历{ if (!p) return; change(p->left, last); if (last) last->right = p; p->left = last; last = p; change(p->right, last);}void main(){ Node *root = create(); Node *tail = NULL; change(root, tail); while (tail) { cout << tail->data << " "; tail = tail->left; } cout << endl;}
22.圆圈中最后剩下的数字:0,1,…,n-1 这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字,求出这个圆圈里剩下的最后一个数字
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
如果不带环:
我们只要判断俩个链表的尾指针是否相等。
相等,则链表相交;否则,链表不相交。
1.先判断带不带环
2.如果都不带环,就判断尾节点是否相等
3.如果都带环,判断一链表上俩指针相遇的那个节点,在不在另一条链表上。
如果在,则相交,如果不在,则不相交。
- 链表问题
- 链表问题
- 链表问题
- C 链表问题
- 链表相交问题
- 链表问题
- 链表相交问题
- 链表问题总结
- 链表问题
- 链表相交问题
- 链表相交问题
- 链表问题
- 链表相交问题
- 循环链表问题
- 链表问题
- 链表排序问题
- 链表问题
- 链表问题(OJ)
- 1010. 一元多项式求导 (25)
- Linux创建目录和文件管理
- 1011. A+B和C (15)
- 1012. 数字分类 (20)
- 笔记
- 链表问题
- 1013. 数素数 (20)
- HorizontalScrollView的使用
- [LeetCode]324. Wiggle Sort II
- 1014. 福尔摩斯的约会 (20)
- 算法导论15-6公司聚会计划Planning a company party
- android 中的Uri详解
- 1015. 德才论 (25)
- POJ 3273 二分法穷举