数据结构——非循环带头结点单链表的递归方法逆置

与循环单链表相比,非循环带头结点单链表的逆置有一个难以处理的点是头结点的处理。


#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;
}
点赞