链表-C语言实现

链式存储线性表的结构体:

typedef int ElemType;        //元素类型

typedef struct Node            //链表结构体
{
    ElemType date;            //链表结点数据域
    struct Node *next;        //链表结点指针域
}Node,*LinkList;

创建链表:

/*
链表的创建操作
使用srand()时,需要引入头文件stdlib.h,即在头文件处添加 #include<stdlib.h>
使用time()时,需要引入头文件time.h,即在头文件处添加 #include<time.h>
使用malloc()时,需要引入头文件malloc.h,即在头文件处添加 #include<malloc.h>
*/ void CreatList(LinkList *L, int n) { LinkList p,r; int i; srand(time(0)); //初始化随机数种子 *L = (LinkList)malloc(sizeof(Node)); //创建链表空间 //不是表空间,是头结点 2018.8.13/于瑞 r = *L; //r为指向L尾部的指针 for(i = 0; i < n; i++) { p = (Node *)malloc(sizeof(Node)); //创建新结点p //Node *与LinkList等价 2018.8.13/于瑞 p->date = rand() % 100 +1; //为新结点的数据域赋值 r->next = p; //使r指针指向p r = p; //将p结点赋值给r,使r继续为表尾结点 } r->next = NULL; //表尾结点指针域为空 }

链式存储的插入函数:

/*
链表的插入操作
*/
Status InsertList(LinkList *L, int i, ElemType e)
{
    int j = 1;        //记录当前位置
    LinkList p,s;
    p = *L;            //将p指向L的头结点
    while(p && j < i)        //判断p是否不为空  且  计数器j是否小于插入的位置i
    {
        p = p->next;        //若是,将指针后移
        j++;                //计数器加1
    }
    if(!p || j > i)            //判断p是否为空  或  计数器j是否大于插入位置i
        return ERROR;        //若是,说明链表为空   或   索引位置有误、

                                            //运行到这,说明已找到需要插入的位置
    s = (LinkList)malloc(sizeof(Node));        //创建新结点s
    s->date = e;                            //将e值赋值给新结点s的数据域
    s->next = p->next;                        //将p结点的指针域赋值给新结点s的指针域
    p->next = s;                            //将新结点s赋值给p结点的指针域
    return OK;                                //操作成功
}

链式存储的删除函数:

/*
链表的删除操作
*/
Status ListDel(LinkList *L, int i, ElemType *e)
{
    int j = 1;            //计数器j
    LinkList p = *L;    //创建指针p指向L
    LinkList q;            //用于记录找到的结点信息,,必须有q,否则无法释放
    while(p->next && j < i)    //判断p是否不为空  且  计数器j是否小于插入的位置i
    {
        p = p->next;    //若是,将指针后移
        j++;            //计数器加1
    }
    if(!(p->next) || j > i)        //判断p是否为空  或  计数器j是否大于插入位置i
        return ERROR;    //若是,说明链表为空   或   索引位置有误

                                //运行到这,说明已找到需要插入的位置
    q = p->next;                //将要删除的结点p->next赋值给q
    *e = q->date;                //将p结点的数据域内容赋值给e
    p->next = q->next;            //将p->next的指针域赋值给p的指针域
    free(q);                    //释放结点q
    return OK;                    //操作成功
}

链式存储的索引查找函数:

/*
线性链表的查询操作
*/
Status GetElem(LinkList L, int i, ElemType *e)
{
    int j = 1;                    //
    LinkList p = L->next;        //声明指针p指向L的计数器第一个节点
    while(p && j < i)                //判断链表是否不为空  并且  计数器j是不是小于所需位置i的大小
    {
        p = p->next;            //若是,是p指向下一节点
        j++;                    //是计数器加1
    }
    if (!p || j>i)                //判断p是否为空  或   计数器j是不是大于所需位置i的大小
        return ERROR;            //若是,说明链表为空或位置索引有误
    *e = p->date;                //若运行此句,说明已找到i位置的元素,将此结点的数据域内容赋值给e
    return OK;                    //返回操作成功
}

链式存储的修改函数:

/*
链表的修改操作
*/
Status UpdateList(LinkList *L, int i, ElemType e)
{
    LinkList p = (*L) ->next;        //使p指向L的第一个结点
    int j = 1;                        //计数器j
    while(p && j < i)                //判断p非空   计数器小于所需位置
    {
        p = p->next;                //指针后移
        j++;                        //计数器加1
    }
    if(!p || j > i)                    //判断p为空    计数器大于所需位置
        return ERROR;                //返回失败
    p->date = e;                    //使p的数据域为e
    return OK;                        //操作成功
}

链式存储的遍历打印函数:

/*
链表的遍历操作
*/
void PrintList(LinkList L)
{
    int j = 1;            //计数器
    LinkList p = L->next;        //使p指向L
    if(!p)
        printf("表空
");
    while(p)
    {
        printf("第%d个元素为%d
",j,p->date);
        p = p->next;
        j++;
    }
    printf("
");
}

整表删除函数:

/*
链表的整表删除操作
*/
Status ClearList(LinkList *L)
{
    int j = 1;            //计数器1
    LinkList p,q;
    p = (*L)->next;                //让p指向L
    while(p)
    {
        q = p->next;            //使q指向p
        free(p);                //释放p
        p = q;                    //使p指向q
    }
    (*L)->next = NULL;            //使头指针为空
    return OK;                    //操作成功
}

主函数:

void main()
{
    LinkList L;            //创建链表L
    int i, e;            //i为元素位置,e为元素内容

    while(true)
    {
        printf("请选择对线性链表的操作:
");
        printf("1.创建
");
        printf("2.插入
");
        printf("3.删除
");
        printf("4.查找
");
        printf("5.修改
");
        printf("6.输出
");
        printf("7.整表删除
");
        printf("8.退出
");
        int a;
        scanf("%d", &a);
        switch(a)
        {
            case 1:
                printf("请输入需要创建元素的个数:");
                scanf("%d", &i);
                if(CreatList(&L, i))
                    printf("创建成功
");
                else
                    printf("创建失败
");
                break;
            case 2:
                printf("请输入需要插入的位置:");
                scanf("%d", &i);
                printf("请输入需要插入的元素:");
                scanf("%d", &e);
                if(InsertList(&L, i, e))
                    printf("插入成功
");
                else
                    printf("插入失败
");
                break;
            case 3:
                printf("请输入需要删除的位置:");
                scanf("%d", &i);
                if(ListDel(&L, i, &e))
                    printf("删除成功
");
                else
                    printf("删除失败
");
                break;
            case 4:
                printf("请输入需要查找的位置:");
                scanf("%d", &i);
                GetElem(L, i, &e);
                printf("第%d个元素为%d
",i,e);
                break;
            case 5:
                printf("请输入需要修改的位置:");
                scanf("%d", &i);
                printf("请输入新的的元素:");
                scanf("%d", &e);
                if(UpdateList(&L, i, e))
                    printf("修改成功
");
                else
                    printf("修改失败
");
                break;
            case 6:
                PrintList(L);
                break;
            case 7:
                if(ClearList(&L))
                    printf("清空成功
");
                else
                    printf("清空失败
");
                break;
            case 8:
                return;
            default:
                printf("选择错误
");
                break;
        }
    }
}

经检测,所有代码均可执行!

原文地址:https://www.cnblogs.com/yurui/p/9498868.html