将带头节点的单循环链表逆置
方法一:
普通循环方法,通俗的讲,只要把每一个结点指向它本来的前一个即可,就像是直接改变了链表概念图中箭头的方向,这一方法就是使用普通的循环打成这个过程。
C语言代码实现:
void reverseList(PList x){
if(x->head!=x->tail&&x->head->next!=x->tail){
PNode p=x->head;
PNode c=NULL,n=x->tail;
//改变尾指针
x->tail=p->next;
do{
c=p->next;
p->next=n;
n=p;
p=c;
}while(p!=x->head);
}
}
方法二:
使用递归方法,每一次逆置一个结点前,首先逆置其后面的结点,除非它的后面是头结点。
C语言代码实现:
void reverseList(PNode x,PList l){
if(x!=l->tail){
reverseList(x->next,l);
x->next->next=x;
}
//处理head和tail
if(x==l->head){
PNode t=x->next;
x->next=l->tail;
l->tail=t;
}
}
完整调试代码:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct Node{
int data;
Node *next;
}Node,*PNode;//节点
typedef struct List{
PNode head;
PNode tail;
int length;
}List,*PList;//链表
void initList(PList x){
PNode headNode=(PNode)malloc(sizeof(Node));
if(!headNode)
exit(0);
headNode->data=0;
headNode->next=headNode;
x->head=headNode;
x->tail=headNode;
x->length=0;
}//初始化链表
int insertNode(PList x,int i,int e){
if(i>x->length)
return 1;
PNode newNode=(PNode)malloc(sizeof(Node));
if(!newNode)
exit(0);
newNode->data=e;
PNode p=x->head;
for(int j=0;j<i;j++)
p=p->next;
newNode->next=p->next;
p->next=newNode;
if(i==x->length)
x->tail=newNode;
x->length++;
return 0;
}//插入结点
int deleteNode(PList x,int i){
if(i>x->length)
return 1;
PNode p=x->head;
for(int j=0;j<i-1;j++)
p=p->next;
PNode delNode=p->next;
p->next=delNode->next;
if(i==x->length)
x->tail=p;
free(delNode);
x->length--;
return 0;
}//删除结点
void outputList(PList x){
PNode p=x->head->next;
for(int i=0;i<x->length;i++){
printf("%3d",p->data);
p=p->next;
}
printf("\n");
}//打印链表
int deleteList(PList x){
while(x->length>0){
deleteNode(x,x->length);
x->length--;
}
free(x->head);
x->head=NULL;
x->tail=NULL;
}//删除链表
void reverseList(PNode x,PList l){
if(x!=l->tail){
reverseList(x->next,l);
x->next->next=x;
}
//处理head和tail
if(x==l->head){
PNode t=x->next;
x->next=l->tail;
l->tail=t;
}
}//递归方法逆置
int main(){
//初始化链表
PList myList=(PList)malloc(sizeof(List));
initList(myList);
//添加节点
int e=0;
printf("请输入要添加的数据(10个):");
for(int i=0;i<10;i++){
scanf("%d",&e);
insertNode(myList,myList->length,e);
}
//逆置前链表
outputList(myList);
//逆置
reverseList(myList->head,myList);
//逆置后链表
outputList(myList);
//删除链表
deleteList(myList);
return 0;
}