与循环单链表相比,非循环带头结点单链表的逆置有一个难以处理的点是头结点的处理。
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct Node{
int data;
Node *next;
}Node,*PNode;//节点
typedef struct List{
PNode head;
int length;
}List,*PList;//链表
void initList(PList x){
PNode headNode=(PNode)malloc(sizeof(Node));
if(!headNode)
exit(0);
headNode->data=0;
headNode->next=NULL;
x->head=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;
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;
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");
}//打印链表
void outputNode(PList x,int j){
PNode p=x->head;
for(int i=0;i<j;i++)
p=p->next;
printf("%d\n",p->data);
}//打印第i个结点
int deleteList(PList x){
while(x->length>0){
deleteNode(x,x->length);
x->length--;
}
free(x->head);
x->head=NULL;
}//删除链表
void reverseList(PNode x,PList l){
if(x->next!=NULL){
reverseList(x->next,l);
if(x!=l->head){
x->next->next=x;
x->next=NULL;
}
}
else{
l->head->next=x;
}
}//递归方法逆置
int main(){
//初始化链表
PList myList=(PList)malloc(sizeof(List));
initList(myList);
//添加节点
int n=0;
printf("请输入要添加几个数据:");
scanf("%d",&n);
int e=0;
printf("请输入要添加的数据:");
for(int i=0;i<n;i++){
scanf("%d",&e);
insertNode(myList,myList->length,e);
}
//逆置前链表
printf("\n逆置前链表:\n");
outputList(myList);
//逆置
reverseList(myList->head,myList);
//逆置后链表
printf("\n逆置后链表:\n");
outputList(myList);
//删除链表
deleteList(myList);
return 0;
}