单链表逆置
来源:互联网 发布:中国好声音改名 知乎 编辑:程序博客网 时间:2024/05/02 20:54
对于单链表的逆置有两种方法可以实现:
(1)利用辅助指针
基本思想:在遍历结点过程中,设置辅助指针,用于记录先前遍历的结点。这样依次编译的过程中只需修改其后继结点的next域即可。
实现代码:
- typedef int DataType; //类型定义
- typedef struct node{ //单链表定义
- DataType data;
- struct node* next;
- }LinkedNode,*LinkList;
- void ReverseList(LinkList& ListHead)
- {
- cout<<"Begin to Reverse the List"<<endl;
- if( (NULL==ListHead)||(NULL==ListHead->next) )return ; //边界检测
- LinkedNode* pPre=ListHead; //先前指针
- LinkedNode* pCur=pPre->next; //当前指针
- LinkedNode* pNext=NULL; //后继指针
- while(pCur!=NULL)
- {
- pNext=pCur->next;
- pCur->next=pPre;
- pPre=pCur;
- pCur=pNext;
- }
- ListHead->next=NULL;
- ListHead=pPre; //记录下新的头结点
- }
示意图:
(2)递归
基本思想:在对当前结点逆置时,先递归地逆置其后继结点,然后将后继结点指向当前结点。
实现代码:
写了两个版本
I、返回值为空
- void ReverseList(LinkedNode* pCur,LinkList& ListHead)
- {
- if( (NULL==pCur)||(NULL==pCur->next) )
- {
- ListHead=pCur;
- }
- else
- {
- LinkedNode* pNext=pCur->next;
- ReverseList(pNext,ListHead); //递归逆置后继结点
- pNext->next=pCur; //将后继结点指向当前结点。
- pCur->next=NULL;
- }
- }
II、返回值为结点类型
- LinkedNode* ReverseList(LinkedNode* pCur,LinkList& ListHead)
- {
- cout<<"Begin to Reverse the List"<<endl;
- if( (NULL==pCur)||(NULL==pCur->next) )
- {
- ListHead=pCur;
- return pCur;
- }
- else
- {
- LinkedNode* pTemp=ReverseList(pCur->next,ListHead); //递归逆置后继结点
- pTemp->next=pCur; //将后继结点指向当前结点
- pCur->next=NULL;
- return pCur;
- }
- }
示意图:
下面给出完整的程序:
- #include<iostream>
- using namespace std;
- const int N=6;
- typedef int DataType;//类型定义
- typedef struct node{ //单链表
- DataType data;
- struct node* next;
- }LinkedNode,*LinkList;
- /****由数组创建单链表****/
- LinkList CreateList(DataType a[N])
- {
- LinkedNode* ListHead=new LinkedNode();
- ListHead->data=a[0];
- ListHead->next=NULL;
- for(int i=N-1;i>=1;i--)
- {
- LinkedNode* p=new LinkedNode();
- p->data=a[i];
- p->next=ListHead->next;
- ListHead->next=p;
- }
- return ListHead;
- }
- /****输出单链表****/
- void PrintList(LinkList ListHead)
- {
- if(NULL==ListHead)cout<<"The List is empty!"<<endl;
- else
- {
- LinkedNode* p=ListHead;
- while(p!=NULL)
- {
- cout<<p->data<<" ";
- p=p->next;
- }
- cout<<endl;
- }
- }
- void ReverseList(LinkedNode* pCur,LinkList& ListHead)
- {
- if( (NULL==pCur)||(NULL==pCur->next) )
- {
- ListHead=pCur;
- }
- else
- {
- LinkedNode* pNext=pCur->next;
- ReverseList(pNext,ListHead); //递归逆置后继结点
- pNext->next=pCur; //将后继结点指向当前结点。
- pCur->next=NULL;
- }
- }
- int main()
- {
- int a[N]={1,2,3,4,5,6};
- LinkedNode* list=CreateList(a);
- PrintList(list);
- LinkedNode*pTemp=list;
- ReverseList(pTemp,list);
- PrintList(list);
- return 0;
- }
原文链接,感谢原作者
自己的实现(里面有不产生任何新节点的实现)
#include <stdio.h>#include <malloc.h>//结构体定义typedef struct node{ int data;//数据域 struct node *next;//指针域}*LinkList, LinkNode;//递归不产生新链表和新节点的逆置方法LinkList resver(LinkList p, LinkList *head){ if(p->next == NULL) { (*head)->next=p;//head为头结点不存放数据 //(*head)=p;//head为首元素可用来存放数据 return p; } resver(p->next, head)->next=p; p->next=NULL; return p;}//递归逆置void Recursive(LinkList *linkHead, LinkNode *pCur){ if ((NULL == pCur) || (NULL == pCur->next)) {*linkHead = (LinkList )malloc(sizeof(LinkNode)*1);//重新添加一个头指针,与原来的结构保持一致 (*linkHead)->next = pCur; } else { LinkNode *pNext = pCur->next; Recursive(linkHead, pNext); pNext->next = pCur; pCur->next = NULL; }}//输出void ShowList(LinkList head,char *prompt){ LinkNode *pCur = head; printf("%s: \n",prompt); while(pCur) { printf("%d\n", pCur->data); pCur = pCur->next; }}int main(){ LinkList head = (LinkList)malloc(sizeof(LinkNode)*1); LinkNode* pCur = head; LinkNode* pNext = NULL; int i = 0; int nodeNumber = 0; printf("请输入要逆置的节点个数 : "); scanf("%d", &nodeNumber); while(i++ < nodeNumber) { pNext = (LinkNode*)malloc(sizeof(LinkNode)*1); pNext->next = NULL; printf("No. %d : ",i); scanf("%d", &(pNext->data)); pCur->next = pNext; pCur = pCur->next; } ShowList(head->next,"逆置之前"); //用第一种方法//pCur = head->next;//从头结点开始 //Recursive(&head, pCur); //ShowList(head->next); //用第二种方法 resver(head->next,&head); LinkList pCur2 = head->next; ShowList(head->next,"逆置之后"); return 0;}
- 单链表逆置
- 单链表逆置
- 单链表逆置。
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 单链表逆置
- 程序(进程)内存分布 解析
- 设置Activity使用系统壁纸作为背景
- Android FragmentManage FragmentTransaction介绍
- 在DM6467上使用C6Accel进行Sobel处理
- 分区表
- 单链表逆置
- 仿QQ窗口抖动
- iOS设计模式之一:MVC模式和单例模式
- 自己的联想Y450笔记本无法连接无线网络的解决办法
- Linux应用监控工具
- HDFS读取副本的选择策略
- Delphi TreeView的GetHitTestInfoAt()方法
- ORACLE 索引
- IP多播技术及其编程