数据结构(2):单向链表的反转

来源:互联网 发布:怎样开淘宝网店代销 编辑:程序博客网 时间:2024/06/15 03:32

单向链表的反转。记住3点:1. 反转;2. 封口;3. 找到新的head。

画图解决问题。1. 画list;2. 画stack(递归的时候)。

不用递归,从前往后反转比较好写。

用递归,从后往前反转。


非递归的做法

1. 没有节点,返回nullptr;

2. 只有1个结点,不用反转,返回头指针;

3. 有大于或等于2个结点,这是要保存连续的3个结点。不然,断开以后,找不到下一个元素在哪里。

如果到尾了(下一个结点是nullptr),就把这个尾巴保存为新的头,最后返回。

转向的时候:

(0) 原始list的头的next先置为nullptr;

(1) 一定要先保存下一个结点,e.g. 用s保存;

(2) 把当前结点p的next指向上一个结点q;

然后再把p、q、s都往前挪一位。(s其实是在while一开始就往后挪了)

用3个指针做!


/************************************************************************//* 单向链表(2):反转qcy2017年1月4日19:35:45*//************************************************************************/#include <iostream>using namespace std;typedef struct LNode{int data;LNode * next;} LNode, *Linklist;void printList(Linklist list) {while (list){cout<<list->data<<" ";list = list->next;}cout<<"\n";}// 反转listLinklist reverseList(Linklist list) {if (!list) // 0个元素return nullptr;else if(!(list->next)) // 1个元素return list; // 不作任何改变// 大于等于2个元素 --> 要保留 连续的三个元素!!! [记住,记住…]else {LNode *p,*q, *s;LNode *newHead;q = list;p = list->next;list->next = nullptr; // 把第一个元素的next至0// 那p有没有为nullptr?? 没有啊!while (p) // 当前节点没有到头{s = p->next; // 1. 把即将反转的结点的下一个先保存下来。不然一会儿找不到。//////////if (!s) // 如果当前的next走到list的末尾了,新链表头就是当前的结点newHead = p; // 2. p的next指向q(转向)p->next = q;// 3. p和q分别往前走q = p;p = s;}return newHead;}}int main () {const int N = 10;int iArray[N] = {1,2,3,4,5,6,7,8,9,10};Linklist list,head,p;list = new LNode;head = list;p = head;// 第1个list->data = iArray[0];list->next = nullptr;// 之后的for (int i = 1;i<N;i++){LNode * node = new LNode;node->data = iArray[i];node->next = nullptr;p->next = node;p = p->next;}printList(head);//////////////////////////////////////////////////////////////////////////// 把list反个顺序 // 多画几个图!!head = reverseList(list); list = head; cout<<"反转list"<<endl; printList(list);system("pause");return 0;}
1 2 3 4 5 6 7 8 9 10
反转list
10 9 8 7 6 5 4 3 2 1

递归做法

Linklist myRerverseRecursion(Linklist head) {// 如果当前节点到了list的末尾了,就返回当前节点if (head == nullptr || head->next == nullptr){return head;} else  {// 1. 继续前进,直到找到list的尾部,作为新的headLinklist newHead = myRerverseRecursion(head->next);// 2. 出了栈(上面的函数结束以后)以后,就反转、封口// (head->next)->next = head; // 简单写法。反转LNode * nextNode = head->next; // 分步写反转nextNode->next = head; // 反转head->next = nullptr; // 封口return newHead; // 不断地返回,使得上面一定能得到list的尾巴(新的头结点)}}
建议:画出stack!画出list!

反转、封口。

0 0
原创粉丝点击