数据结构:双向链表的基本操作

设计算法,实现双向链表的建立、元素的查找、插入、删除等操作。

(1)从键盘输入整数以-999结束,建立数据域为整数的双向链表。

(2)从键盘输入1个序号,在双向链表中查找该结点的位置。若找到,输出结点的位置;若找不到,则显示“找不到”。

(3)从键盘输入两个整数,一个表示欲插入的位置i,另一个表示欲插入的数值x,将x插入在i位置上,输出链表所有结点值,观察输出结果。

(4)从键盘输入一个整数,表示欲删除结点的位置,删除该结点,然后输出链表所有结点值,观察输出结果。

(5)要求程序通过一个主菜单进行控制,在主菜单界面通过选择菜单项的序号来调用各功能函数。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef COMMON_H
#define COMMON_H
#define ERROR 0
#define OK 1
#define FALSE -1
#define TRUE 1
#endif // COMMON_H
#ifndef Datastructures_H
#define Datastructures_H

typedef struct DNode
{
    int data;
    struct DNode *next;
    struct DNode *prev;
}DNode,* DoulbeList;


#endif  //DataStructures_H
#ifndef Functions_H
#define Functions_H

int menu_select();    //菜单驱动程序
int CreatDNode(DNode *DoubleList);
int FindNode(DNode *DoubleList,int n);
int AddNode(DNode *DoubleList,int n);
int DelNode(DNode *DoubleList,int n);
int PrintNode(DNode *DoubleList,int n);
void freelink(DNode *DoubleList);

#endif  //Functions_H

int menu_select()
{
    int sn;
    printf("       双向链表基本操作\n");        //显示菜单
    printf("==============================\n");
    printf("   1、建立双向链表(-999结束)\n");
    printf("   2、查找第i个位置数据\n");
    printf("   3、在第i个节点插入值x\n");
    printf("   4、删除第i个节点\n");
    printf("   5、显示双向链表数据\n");
    printf("   0、退出通讯录管理系统\n");
    printf("==============================\n");
    printf("  请选择0--5:  ");

    for(;;)        //菜单功能选择
    {
        scanf("%d",&sn);
        getchar();
        if(sn<0 || sn>5)
            printf("\n\t 输入选择错误,请重新选择 0--5: ");
        else
            break;
    }
    return sn;
}
/*TODO:创建双向链表
      功能描述:创建双向链表,通过键盘输入创建首节点a,使头结点指向a,然后循环输入首节点之后的节点,直到输入-999,退出设置节点
      如果输入参数为NULL,打印error,并返回
      键盘提示输入首节点,打印“请输入第1个节点数值”
      键盘提示输入首节点之后节点,打印“请输入第%d个节点数值”
      参数说明:DoubleList 表示头节点指针
      返回值说明:n 整型 链表的长度
 */
int CreatDNode(DNode *DoubleList)
{
    int n=1,i,a;
    DNode *p1,*p2=DoubleList;
    printf("请输入第1个节点数值\n");
    scanf("%d%*c",&a);
    while(a!=-999)
    {
        p1= (DNode *)malloc(sizeof(DNode));
        if(p1==NULL)
         {
            printf("error\n");
            return ERROR;
        }
        p1->data=a;
        p2->next=p1;
        p1->prev=p2;
        p2=p1;
        printf("请输入第%d个节点数值\n",++n);
        scanf("%d%*c",&a);
    }
    p2->next=NULL;
    return n;
}
/*TODO:查找结点
      功能描述:在双向链表中查找结点i的位置,并打印数据
      键盘提示输入节点序号,打印“请输入需要查找的节点序号”
      节点i大于n小于1打印提示“输入的序号错误,请重新输入”
      查到节点i的数据后打印“第%d个节点数据为%d\n” 返回常量TRUE
      参数说明:DoubleList 表示头节点指针
         n 链表的长度
      返回值说明:TRUE 成功
 */
int FindNode(DNode *DoubleList,int n)
{
    int i,j;
    DNode *p=DoubleList;
    scanf("%d%*c",&i);
    if(i>n||i<1)
    {
        printf("输入的序号错误,请重新输入\n");
        scanf("%d%*c",&i);
    }

    for(j=0;j<i;j++)
    {
        p=p->next;
    }
    if(j==i)
    {
        printf("%d\n",p->data);
        return TRUE;
    }
}
/*TODO:插入数据
      功能描述:在位置i插入数据x,使位置i的节点向前指向i-1节点,向后指向i+1节点
      键盘提示输入节点序号,打印“请输入插入的节点序号”
      节点i大于n小于1打印提示“输入的序号错误,请重新输入”
      键盘提示输入节点i的数据x,打印“请输入数据”
      参数说明:DoubleList 表示头节点指针
         n 链表的长度
      返回值说明:TRUE 成功
 */
int AddNode(DNode *DoubleList,int n)
{
    DNode *s,*p=DoubleList;
    int i,j=0,x;
    printf("请输入插入的节点序号\n");
    scanf("%d%*c",&i);
    if(i>n||i<1)
    {
        printf("输入的序号错误,请重新输入\n");
        scanf("%d%*c",&i);
    }
    while(p->next!=NULL&&(j<i))
    {
        p=p->next;
        j++;
    }
    if(j==i)
    {
        s=(DNode*)malloc(sizeof(DNode));
        printf("请输入数据\n");
        scanf("%d%*c",&x);
        if(s)
        {
            s->data=x;
            s->prev=p->prev;
            p->prev->next=s;
            s->next=p;
            p->prev=s;
            return TRUE;
        }
    }



}
/*TODO:删除节点
      功能描述:删除节点i,使位置i-1的节点指向i+1节点
      键盘提示输入节点序号,打印“请输入删除的节点序号”
      节点i大于n小于1打印提示“输入的序号错误,请重新输入”
       参数说明:DoubleList 表示头节点指针
         n 链表的长度
      返回值说明:TRUE 成功
 */
int DelNode(DNode *DoubleList, int n)
{
    DNode *p=DoubleList;
    int i,j=0;
    printf("请输入删除的节点序号\n");
    scanf("%d%*c",&i);
    if(i>n||i<1)
    {
        printf("输入的序号错误,请重新输入\n");
        scanf("%d%*c",&i);
    }
    while(p->next!=NULL&&(j<i))
    {
        p=p->next;
        j++;
    }
    if(j==i)
    {
        p->prev->next=p->next;
        p->next->prev=p->prev;
        free(p);
        return TRUE;
    }


}
/*TODO:打印各个节点信息
      功能描述:键盘输出打印“第%d个节点数据为%d\n”
      参数说明:DoubleList 表示头节点指针
         n 链表的长度
      返回值说明:TRUE 成功
 */
int PrintNode(DNode *DoubleList,int n)
{
    DNode *p=DoubleList->next;
    int i=1;
    while(p!=NULL&&i<=n)
    {
        printf("第%d个节点数据为%d\n",i,p->data);
        i++;
        p=p->next;
    }
    return TRUE;
}
/**
      输入参数 :  *DoubleList 表示头节点
      输出参数 :   无
      释放链表
 */
void freelink(DNode *DoubleList)
{
    DNode *p;
    while(DoubleList)
    {
        p=DoubleList;
        DoubleList=DoubleList->next;
        free(p);
    }
}
int main()
{
    int n=0;
    DNode *DoubleList;
    DoubleList = (DNode *)malloc(sizeof(DNode));
    for(;;)     // 无限循环,选择0 退出
    {
        switch(menu_select())     // 调用菜单函数,按返回值选择功能函数
        {
            case 1:
                printf(" 建立双向链表(-999结束)\n");
                n=CreatDNode(DoubleList);
                if (n == -1)
                    printf("error1");
                break;
            case 2:
                printf(" 查找第i个位置数据\n");
                FindNode(DoubleList,n);
                break;
            case 3:
                printf(" 在第i个节点插入值x\n");
                AddNode(DoubleList,n);
                n++;
                break;
            case 4:
                printf(" 删除第i个节点\n");
                DelNode(DoubleList,n);
                n--;
                break;
            case 5:
                printf("显示链表\n");
                PrintNode(DoubleList,n);
                break;
            case 0:
                printf(" 再见!\n");                //退出系统
                freelink(DoubleList);
                return 0;
        } // switch语句结束
    } // for循环结束
    return 0;
} // main()函数结束

 

posted @ 2022-06-22 10:25  Oo名字不好取oO  阅读(199)  评论(0)    收藏  举报