用递归删除各种节点

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#define MAXSIZE 1000
typedef int ElemType;
typedef struct node{    //定义链表节点类型
    ElemType data;
    struct node * next;
} Node;
typedef Node *LinkedNode;

/*[1] 求以h为头指针的单链表的节点个数 */
int GetNodeNum(LinkedNode &h)
{
    if(h==NULL)
        return 0;
    else 
        return GetNodeNum(h->next) + 1;
}
/*[2] 正向显示以h为头指针的单链表的所有节点值 */
void PrintForward(LinkedNode &h)
{
    if(h==NULL)    //链表到头,结束输出
        return ;
    printf("%d ",h->data);
    PrintForward(h->next);    //输出下一个元素值
}
/*[3] 反向显示以h为头指针的单链表的所有节点值 */
void PrintReverse(LinkedNode &h)
{
    if(h==NULL)
        return ;
    PrintReverse(h->next);    //链表跑到头,再开始输出
    printf("%d ",h->data);
}
/*[4] 删除以h为头指针的单链表中值为x的第一个节点 */
bool DeleteFirstX(LinkedNode &h,ElemType x)
{
    //递归出口
    if(h==NULL)
        return false;
    else if(h->data==x){        //第一个节点就是要找的节点,删除
        if(h->next==NULL){    //只有一个节点
            free(h);
            h = NULL;
            return true;
        }
        LinkedNode p;
        p = h;
        h = h->next;
        free(p);
        return true;
    }
    else if(h->next!=NULL){
        if(h->next->data==x){    //找到节点,删除
            LinkedNode p;
            p = h->next;
            h->next = p->next;
            free(p);
            return true;
        }
    }
    //递归体
    if(DeleteFirstX(h->next,x))
        return true;
    else 
        return false;
}
/*[5] 删除以h为头指针的单链表中值为x的所有节点 */
void DeleteAllX(LinkedNode &h,ElemType x)
{
    if(h==NULL)
        return ;
    if(h->data==x){        //第一个节点就是要找的节点,删除
        if(h->next==NULL){    //只有一个节点
            free(h);
            h = NULL;
            return ;
        }
        LinkedNode p;
        p = h;
        h = h->next;
        free(p);
        DeleteAllX(h,x);
    }
    else if(h->next==NULL)    //递归出口
        return ;
    else if(h->next->data==x){    //找到节点,删除
        LinkedNode p;
        p = h->next;
        h->next = p->next;
        free(p);
        DeleteAllX(h,x);
    }
    else
        DeleteAllX(h->next,x);
}

/*[6] 删除以h为头指针的单链表中最大节点值 */
void DeleteMaxNode(LinkedNode &h,LinkedNode c,LinkedNode p)
{
    if(h==NULL)
        return ;
    if(c->next==NULL){    //到头,开始删除
        if(p->next ==NULL){
            free(p);
            h = NULL;
            return ;
        }
        if(p==h && p->data > p->next->data){    //第一个节点是要删除的节点
            h = h->next;
            free(p);
            return ;
        }
        else{
            LinkedNode q = p->next;
            p->next = q->next;
            free(q);
            return ;
        }
    }
    if(c->next->data > p->next->data)
        p = c;
    DeleteMaxNode(h,c->next,p);
}
/*[7] 删除以h为头指针的单链表中最小节点值 */
void DeleteMinNode(LinkedNode &h,LinkedNode c,LinkedNode p)
{
    if(h==NULL)
        return ;
    if(c->next==NULL){    //到头,开始删除
        if(p->next ==NULL){
            free(p);
            h = NULL;
            return ;
        }
        if(p==h && p->data < p->next->data){    //第一个节点是要删除的节点
            h = h->next;
            free(p);
            return ;
        }
        else{
            LinkedNode q = p->next;
            p->next = q->next;
            free(q);
            return ;
        }
    }
    if(c->next->data < p->next->data)
        p = c;
    DeleteMinNode(h,c->next,p);
}

/* 1. 初始化单链表 */
LinkedNode LinkedListInit()
{
    LinkedNode head = (Node*)malloc(sizeof(Node));
    head->next = NULL;
    return head;
}
 
/* 2. 清空单链表 */
void LinkedListClear(LinkedNode &L)
{
    //L为头指针
    while(L){    //依次清空节点,直到头指针指向的下一个节点的地址为空
        LinkedNode t;
        t = L;
        L = t->next;
        free(t);
    }
    return ;
}

/* 3. 用尾插法建立单链表 */
LinkedNode  LinkedListCreat( LinkedNode L,ElemType a[],int n )    //讲数组a中的元素以尾插法放入链表中
{
    int i;
    LinkedNode p = L;
    p->data = a[1];
    for(i=2;i<=n;i++){
        LinkedNode q = (LinkedNode)malloc(sizeof(Node));
        q->data = a[i];
        q->next = NULL;
        p->next = q;
        p = q;
    } 
    return L;
}

int Menu()
{
    int in;
    printf("[1] 重新建立一个链表\n");
    printf("[2] 求以h为头指针的单链表的节点个数\n");
    printf("[3] 正向显示以h为头指针的单链表的所有节点值\n");
    printf("[4] 反向显示以h为头指针的单链表的所有节点值\n");
    printf("[5] 删除以h为头指针的单链表中值为x的第一个节点\n");
    printf("[6] 删除以h为头指针的单链表中值为x的所有节点\n");
    printf("[7] 删除以h为头指针的单链表中最大节点值\n");
    printf("[8] 删除以h为头指针的单链表中最小节点值\n");
    printf("[0] 按其他键退出\n");
    scanf("%d",&in);
    return in;
}
LinkedNode Reply(LinkedNode head,int in)
{
    int i,n,x;
    int a[MAXSIZE+1];
    switch(in){
        case 1:    //重新建立一个链表
            LinkedListClear(head);
            head = LinkedListInit();
            printf("你要输入多少个数据?\n");
            scanf("%d",&n);    //输入链表大小
            printf("请依次输入数据:\n");
            for(i=1;i<=n;i++) 
                scanf("%d",&a[i]);    
            head = LinkedListCreat(head,a,n);
            printf("链表建立成功!\n");
            break;

        case 2:    //求以h为头指针的单链表的节点个数
            printf("单链表的节点个数为:%d\n",GetNodeNum(head));
            break;

        case 3:    //正向显示以h为头指针的单链表的所有节点值
            printf("链表中元素依次为(正向):\n");
            PrintForward(head);
            printf("\n");
            break;

        case 4:    //反向显示以h为头指针的单链表的所有节点值
            printf("链表中元素依次为(反向):\n");
            PrintReverse(head);
            printf("\n");
            break;

        case 5:    //删除以h为头指针的单链表中值为x的第一个节点
            printf("输入你要删除的元素的值?\n");
            scanf("%d",&x);
            if(DeleteFirstX(head,x))
                printf("删除成功!\n");
            else 
                printf("删除失败!\n");
            printf("链表中元素依次为(正向):\n");
            PrintForward(head);
            printf("\n");
            break;

        case 6:    //删除以h为头指针的单链表中值为x的所有节点
            printf("输入你要删除的元素的值?\n");
            scanf("%d",&x);
            n = GetNodeNum(head);
            DeleteAllX(head,x);
            i = GetNodeNum(head);
            if(n!=i)
                printf("删除成功!\n");
            else
                printf("删除失败!\n");
            printf("链表中元素依次为(正向):\n");
            PrintForward(head);
            printf("\n");
            break;

        case 7:    //删除以h为头指针的单链表中最大节点值
            n = GetNodeNum(head);
            DeleteMaxNode(head,head,head);
            i = GetNodeNum(head);
            if(n!=i)
                printf("删除成功!\n");
            else
                printf("删除失败!\n");
            printf("链表中元素依次为(正向):\n");
            PrintForward(head);
            printf("\n");
            break;

        case 8:    //删除以h为头指针的单链表中最小节点值
            n = GetNodeNum(head);
            DeleteMinNode(head,head,head);
            i = GetNodeNum(head);
            if(n!=i)
                printf("删除成功!\n");
            else
                printf("删除失败!\n");
            printf("链表中元素依次为(正向):\n");
            PrintForward(head);
            printf("\n");
            break;

        default:
            printf("Bye~\n");
            exit(1);
    }
    system("pause");
    system("cls");
    return head;
}
int main()
{
    int in;    //存储输入命令
    LinkedNode head = NULL;
    while(1){
        in = Menu();
        head = Reply(head,in);    //响应命令                                                                    
    }
    return 0;
}

 

posted @ 2015-12-02 12:25  曾-杰  阅读(672)  评论(0编辑  收藏  举报