C递归实现单向链表的反转

来源:互联网 发布:腾讯微云for mac 编辑:程序博客网 时间:2024/05/21 14:22

  #include <stdio.h>
  #include <stdlib.h>
  //#include <conio.h>

   /*链表节点存储的数据*/
   typedef char ElemType;


   /*链表节点结构*/
   typedef struct LinkListNode
   {
       ElemType data;
       struct LinkListNode * next;
   } *LinkList,*pNode,LinkListNode;


   /*递归实现反转不带头节点的单向链表

           pNode:PerNode        前一节点指针
           pNode:CurrentNode        后一节点指针
           visit            自定义节点访问函数
   */
   LinkList ReverseLinkList( pNode PreNode, pNode CurrentNode, void(*visit)(ElemType e) )
   {
   
       if(!CurrentNode)                /*如果当前节点指针为空,则返回NULL,此种情况只有在*/
           return NULL;            /*链表头指针为空时才可能执行到*/
        printf("%s %d\n",__FUNCTION__,CurrentNode->data);
       if(!CurrentNode->next)            /*如果下一节点指针为空,则将当前节点next指针指向上一节点,并*/
       {                    /*返回当前节点指针,次种情况只有在当前节点为尾节点时才能执行到*/
           visit(CurrentNode->data);
           CurrentNode->next=PreNode;
           return CurrentNode;
       }
       else                    /*其他节点的情况,先调用递归函数反转后续节点,再反转当前节点*/
       {                    /*并将递归函数返回来的尾节点指针向上层函数返回*/
           LinkList FirstNode;

           FirstNode=ReverseLinkList(CurrentNode,CurrentNode->next,visit);

           visit(CurrentNode->data);
           CurrentNode->next=PreNode;
           return FirstNode;            /*返回的是尾节点的指针,即反转后新链表的头指针*/
       }
   }

   /*自定义链表节点访问函数*/
   void visit(ElemType e)
   {
       printf("process node %c\n",e);
   }


   /*打印链表*/
   void PrintLinkList(LinkList PL)
   {
       printf("\n--------------------------\n");
       while(PL)
       {
           printf("%c  ",PL->data);
           PL=PL->next;
       }
       printf("\n--------------------------\n");
   }

   /*用键盘输入初始化一个链表,参数为链表头指针地址*/
   void InitializeLinkList(LinkList * Head)
   {
       pNode EndNode=*Head;    /*总是指向链表最后一个节点*/

       pNode TempNode=NULL;    /*临时节点,存放当前输入的链表节点*/
       int i=1;            /*节点记数*/
       char getEnter;

       printf("please input characters of the linklist(end with Enter):\n");

       /*开始构造不带头节点的单向链表*/
       while(1)/*不停地循环接受字符*/
       {
           TempNode=(pNode)malloc(sizeof(LinkListNode));    /*为当前输入的链表节点分配空间*/
           TempNode->next=NULL;

           printf("Node[%d]:",i);
           TempNode->data=getchar();    /*接受字符*/


           if(TempNode->data== 'c' )    /*如果直接回车,则结束链表的输入*/
           {
               TempNode=NULL;
               break;
           }
           getEnter=getchar();        /*接受输完字符后的回车*/

            if(i==1)                /*如果当前输入的是第一个节点,则让头指针指向它*/
            {
                *Head=TempNode;
                EndNode=*Head;
            }

            EndNode->next=TempNode;        /*将当前输入的节点接到链表尾端*/
            EndNode=TempNode;

            i++;
        }
    }

    int main()
    {
        LinkList head=NULL;            /*声明头指针*/

        InitializeLinkList(&head);            /*初始化链表*/

        PrintLinkList(head);            /*打印原链表*/

        head=ReverseLinkList(NULL,head,visit);    /*调用反转函数*/

        PrintLinkList(head);            /*打印反转后的链表*/

        return 1;
    }