【数据结构合集】线性表的链式存储

该文章提供了一个C语言实现的单链表操作程序,包括初始化链表、清空链表、检查链表是否为空、打印链表长度、显示元素、按位置获取值、按值获取位置、按位置插入、按位置删除、按值删除、头压入元素、尾压入元素、头弹出元素、尾弹出元素以及单链表的合并等功能。用户可以交互式地进行这些操作。
摘要由CSDN通过智能技术生成

⭐️写在前面的话⭐️

📒博客主页: 程序员好冰
🎉欢迎 【点赞👍 关注🔎 收藏⭐️ 留言📝】
📌本文由 程序员好冰 原创,CSDN 首发!
📆入站时间: 🌴2022 年 07 月 13 日🌴
✉️ 是非不入松风耳,花落花开只读书。
💭推荐书籍:📚《Java编程思想》,📚《Java 核心技术卷》
💬参考在线编程网站:🌐牛客网🌐力扣
🍭 作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!🍭


线性表的链式存储

定义的当前结点什么时候应该指向头结点,什么时候应该指向第一个结点?

  • 打印的时候,不应该,也不会打印头结点,因此这里应该指向第一个结点;
  • 插入的时候,原来在头结点的位置可能会插入元素,此时应该指向头结点;
  • 需要指向头结点的操作:按位置插入元素、按位置删除元素、按值删除元素(全部删除)、头插法、尾插法、头弹出、尾弹出、单链表合并。
  • 需要指向第一个结点的操作:清空链表、检查表是否为空、求表的长度、打印表元素、按位置取值、按值获取位置。

两行代码的区别:

*L=(linkList)malloc(sizeof(Node));
/*
	分配一个具有一个结点大小的空间
	并强制转换为linkList类型
	是链表中的一个头结点
	并让这个链表L指向这个头结点
*/

L=(linkList*)malloc(sizeof(Node*));
/*
	分配一个具有结点指针大小的空间
	注意:这里的结点本身就是指针,Node*相当于一个二级指针
	并强制转换为linkList*类型
	并让链表的首地址指向这个二级指针
	显然:这样进行空间分配是错误的
*/

单链表按值删除,全部删除

image-20230322170759685

自定义声明

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

//定义状态码
#define OK 1
#define ERROR 0

//自定义类型
typedef int Status;//定义状态码的类型
typedef int ElemType;//定义每一个元素的类型

//定义结构体
typedef struct Node
{
    ElemType data;//指数据元素
    /*一个指向自己的指针*/
    struct Node *next;//指指针域,即下一个节点的地址(指针)
}Node;

//定义链表的类型,同样为 Node* 类型
typedef struct Node *linkList;

函数声明

//声明函数
//对表进行操作
Status init_list(linkList*);//1初始化链表
Status clear_list(linkList*);//2清空链表
Status check_list_isEmpty(linkList);//3检查表是否为空
Status show_list_length(linkList);//4打印当前表的长度

/*对表中数据进行操作*/
//以下3个函数,不会对表造成改变,故传入SqList
Status show_list(linkList);//5显示表中所有元素
Status getElem_by_local(linkList,int);//6按位置获取值
Status getIndex_by_value(linkList,ElemType);//7按值获取位置

//以下7个函数,会对表造成改变,故传入SqList*,指针
Status insert_list_by_local(linkList*,int,ElemType);//8按位置插入
Status delete_list_by_local(linkList*,int);//9按位置删除
Status delete_list_by_value(linkList*,ElemType);//10按值删除(全部删除)
Status push_elem_head(linkList*,ElemType);//11头压入元素
Status push_elem_foot(linkList*,ElemType);//12尾压入元素
Status pop_elem_head(linkList*);//13头弹出元素
Status pop_elem_foot(linkList*);//14尾弹出元素

Status union_lists(linkList*,linkList*);//15单链表的合并

1、初始化链表

//1初始化链表
Status init_list(linkList *L)
{
    /*生成一个大小为Node的头结点,并让L指向头结点*/
    *L=(linkList)malloc(sizeof(Node));
    //如果分配的这个L不存在,说明初始化失败
    if(!L){
        printf("初始化失败,请重新操作...\n");
        return ERROR;
    }
    /*初始化成功的操作*/
    (*L)->next=NULL;//将指针域置空
    printf("初始化链表成功.\n");
    return OK;
}

2、清空链表

//2清空链表
Status clear_list(linkList *L)
{
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;//指当前结点
    linkList q;//记录下一个结点的位置
    p=(*L)->next;//指向第一个结点
    while(p){//没有达到表尾
        q=p->next;//记录下一个结点的位置,防止数据丢失
        free(p);//释放当前结点
        p=q;//将当前这个结点后移
    }
    (*L)->next=NULL;//将头结点的指针域置空
    printf("清空链表成功.\n");
    return OK;
}

3、检查表是否为空

//3检查表是否为空
Status check_list_isEmpty(linkList L)
{
    if(L->next){
        printf("链表不为空.\n");
        return OK;
    }else
    {
        printf("链表为空.\n");
    }
    return OK;
}

4、打印当前表的长度

//4打印当前表的长度
Status show_list_length(linkList L)
{
    if(!L->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;//指向当前结点
    p=L->next;//指向第一个结点
    int count;
    count =0;
    while(p){
        count++;
        p=p->next;
    }
    printf("表中一共有%d个元素.\n",count);
    return OK;
}

5、显示表中所有元素

//5显示表中所有元素
Status show_list(linkList L)
{
    if(!L->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;
    p=L->next;//指向第一个结点
    printf("表为:");
    while(p){
        printf("%d  ",p->data);
        p=p->next;
    }
    printf("\n");
    return OK;
}

6、按位置获取值

//6按位置获取值
Status getElem_by_local(linkList L,int key)
{
    if(!L->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;//指当前结点
    p=L->next;
    int i;//计数器,向后移动指针
    i=1;
    while(p&&i<key){
        p=p->next;
        i++;
    }
    if(!p||i>key){
        printf("输入的位置有误,请重新操作.\n");
        return ERROR;
    }
    printf("第%d个元素为%d.\n",key,p->data);
    return OK;
}

7、按值获取位置

//7按值获取位置
Status getIndex_by_value(linkList L,ElemType value)
{
    if(!L->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;
    p=L->next;
    int i=0;
    int count=0;
    while(p){
        i++;
        if(p->data==value){
            printf("表中第%d个元素值为%d.\n",i,value);
            count++;
        }
        p=p->next;
    }
    if(count>0){
        printf("链表中一共有%d个值为%d的元素.\n",count,value);
    }
    if(count==0){
        printf("链表中找不到值为%d的元素.\n",value);
    }
    return OK;
}

8、按位置插入

//8按位置插入
Status insert_list_by_local(linkList *L,int key,ElemType value)
{
    int i;//充当计数器
    linkList p;//指当前的结点
    linkList s;//指新加入的结点,由于链表由结点构成,插入元素就是插入结点
    i=1;//从第一个结点开始找,而不是头结点
    /*
        循环成立的条件:
        1、当前结点不为NULL
        2、由于链表查找元素是通过结点一个一个地查找,需要的条件是i等于key
    */
    p=*L;//p指向头结点

    //while循环的作用:挨个向后遍历结点
    while(p&&i<key){
        p=p->next;
        i++;
    }
    /*异常处理*/
    //1、p为NULL;2、i>key
    if(!p||i>key){
        printf("输入的位置有误,请重新操作.\n");
        return ERROR;
    }
    //创建新结点
    s=(linkList)malloc(sizeof(Node));
    s->data=value;
    s->next=p->next;
    p->next=s;
    show_list(*L);
    return OK;
}

9、按位置删除

//9按位置删除
Status delete_list_by_local(linkList *L,int key)
{
    /*
        p为删除结点的前一个结点
        q为要删除的结点
    */
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }

    linkList p;
    linkList q;
    ElemType temp_elem;
    p=*L;//指定为头结点
    int i;
    i=1;
    while(p->next&&i<key){
        p=p->next;
        i++;
    }
    if(!(p->next)||i>key){
        printf("输入的位置有问题,请重新输入.\n");
        return ERROR;
    }
    /*
        找到的条件:
        p->next不为NULL
        i等于key
    */
     q=p->next;
     temp_elem=q->data;//记录将要删除的值,方便打印
     p->next=q->next;
    free(q);
    printf("第%d个元素%d删除成功.\n",key,temp_elem);
    show_list(*L);
    return OK;
}

10、按值删除(全部删除)

//10按值删除(全部删除)
Status delete_list_by_value(linkList *L,ElemType value)
{
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList q;//指向要删除的结点
    linkList p;//指向要删除的前一个结点
    p=*L;//指向头结点
    int count;
    count=1;
    int sum;
    sum=0;
    //p->next达到NULL,说明是最后一个结点了,直接退出
    while(p->next){
        q=p->next;
        if(q->data==value){
            p->next=q->next;
            free(q);
            sum++;
            printf("第%d个值为%d的元素被删.\n",count,value);
        }else
        {
            p=p->next;//值不匹配,则指针向后移
        }
        count++;
    }
    if(sum==0){
        printf("链表中没有%d这个值,请重新操作...\n",value);
        return ERROR;
    }
    printf("链表中一共有%d个这样的值.\n",sum);
    show_list(*L);
    return OK;
}

11、头压入元素

//11头压入元素
Status push_elem_head(linkList *L,ElemType value)
{
    linkList p;
    p=*L;
    linkList s;
    s=(linkList)malloc(sizeof(Node));
    s->data=value;
    s->next=p->next;
    p->next=s;
    show_list(*L);
    return OK;
}

12、尾压入元素

//12尾压入元素
Status push_elem_foot(linkList *L,ElemType value)
{
    linkList p;//指当前结点
    linkList s;//新产生的结点
    p=*L;
    while(p->next){
        p=p->next;
    }
    s=(linkList)malloc(sizeof(Node));
    s->data=value;
    p->next=s;
    s->next=NULL;
    show_list(*L);
    return OK;
}

13、头弹出元素

//13头弹出元素
Status pop_elem_head(linkList *L)
{
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;
    p=*L;//指向头结点
    linkList q;//指当前结点
    q=p->next;
    ElemType temp_elem;
    temp_elem=q->data;
    p->next=q->next;
    free(q);
    printf("表头元素%d被弹出.\n",temp_elem);
    show_list(*L);
    return OK;
}

14、尾弹出元素

//14尾弹出元素
Status pop_elem_foot(linkList *L)
{
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;
    p=*L;
    linkList q;

    ElemType temp_elem;
    while(p->next){
        q=p->next;
        if(q->next==NULL){
            break;
        }
        p=p->next;
    }
    temp_elem=q->data;
    free(q);
    p->next=NULL;
    printf("表尾元素%d被弹出.\n",temp_elem);
    show_list(*L);
    return OK;
}

15、单链表的合并

//15单链表的合并
Status union_lists(linkList *A,linkList *B)
{
    linkList pa;//指向头结点
    pa=*A;
    linkList pb;
    pb=*B;

    if(!(*A)->next){
        show_list(*B);
        return ERROR;
    }

    if(!(*B)->next){
        show_list(*A);
        return ERROR;
    }

    linkList cur;//指向当前结点
    while(pa->next){
        cur=pa->next;
        if(cur->next==NULL){
            break;
        }
        pa=pa->next;
    }

    cur->next=pb->next;
    return OK;
}

主函数

int main()
{
    linkList L;
    printf("请继续操作...\n");
    while(1){
        int input;
        int key;
        ElemType value;
        printf("\n==========================\n");
        printf("1、初始化链表.\n");
        printf("2、清空链表.\n");
        printf("3、检查链表是否为空.\n");
        printf("4、打印表的长度.\n");
        printf("5、打印表中所有元素.\n");
        printf("6、按位置实现查找值.\n");
        printf("7、按值实现查找位置.\n");
        printf("8、按位置实现插入.\n");
        printf("9、按位置实现删除.\n");
        printf("10、按值实现删除.\n");
        printf("11、头部压入元素.\n");
        printf("12、尾部压入元素.\n");
        printf("13、头部弹出元素.\n");
        printf("14、尾部弹出元素.\n");
        printf("==========================\n");
        printf("请输入对应操作的序号:");
        scanf("%d",&input);
        switch(input)
        {
        case 1:
            init_list(&L);
            break;
        case 2:
            clear_list(&L);
            break;
        case 3:
            check_list_isEmpty(L);
            break;
        case 4:
            show_list_length(L);
            break;
        case 5:
            show_list(L);
            break;
        case 6:
            printf("请输入要查找的位置(K):");
            scanf("%d",&key);
            getElem_by_local(L,key);
            break;
        case 7:
            printf("请输入要查找的值(V):");
            scanf("%d",&value);
            getIndex_by_value(L,value);
            break;
        case 8:
            printf("请输入要插入的位置和值(K,V):");
            scanf("%d,%d",&key,&value);
            insert_list_by_local(&L,key,value);
            break;
        case 9:
            printf("请输入要删除的位置(K):");
            scanf("%d",&key);
            delete_list_by_local(&L,key);
            break;
        case 10:
            printf("请输入要删除的值(V):");
            scanf("%d",&value);
            delete_list_by_value(&L,value);
            break;
        case 11:
            printf("请输入要头压入的值(V):");
            scanf("%d",&value);
            push_elem_head(&L,value);
            break;
        case 12:
            printf("请输入要尾压入的值(V):");
            scanf("%d",&value);
            push_elem_foot(&L,value);
            break;
        case 13:
            pop_elem_head(&L);
            break;
        case 14:
            pop_elem_foot(&L);
            break;
        case 15:
            printf("\nTestTestTestTestTestTestTestTestTestTestTestTestTest\n");
            printf("单链表合并测试:\n");
            ElemType value_A,value_B;
            int flag;
            linkList A;
            init_list(&A);
            printf("初始化A表(使用尾插法,以1024结束):\n");
            while(1){
                scanf("%d",&value_A);
                if(value_A==1024){
                    break;
                }
                push_elem_foot(&A,value_A);
            }
            printf("A");
            show_list(A);

            linkList B;
            init_list(&B);
            printf("初始化B表(使用尾插法,以1024结束):\n");
            while(1){
                scanf("%d",&value_B);
                if(value_B==1024){
                    break;
                }
                push_elem_foot(&B,value_B);
            }
            printf("B");
            show_list(B);

            printf("ccccccccccccccccccccccccccccccccccc\n");
            printf("A");
            show_list(A);
            printf("B");
            show_list(B);
            printf("ccccccccccccccccccccccccccccccccccc\n");

            printf("\n合并之后,");

            flag=union_lists(&A,&B);

            if(flag){
                show_list(A);
            }
            printf("\nTestTestTestTestTestTestTestTestTestTestTestTestTest\n");
            break;
        default:
            printf("输入的序号有误,请重新输入...\n");
            break;
        }
    }
    return 0;
}

程序源码

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

//定义状态码
#define OK 1
#define ERROR 0

//自定义类型
typedef int Status;//定义状态码的类型
typedef int ElemType;//定义每一个元素的类型

//定义结构体
typedef struct Node
{
    ElemType data;//指数据元素
    /*一个指向自己的指针*/
    struct Node *next;//指指针域,即下一个节点的地址(指针)
}Node;

//定义链表的类型,同样为 Node* 类型
typedef struct Node *linkList;

//声明函数
//对表进行操作
Status init_list(linkList*);//1初始化链表
Status clear_list(linkList*);//2清空链表
Status check_list_isEmpty(linkList);//3检查表是否为空
Status show_list_length(linkList);//4打印当前表的长度

/*对表中数据进行操作*/
//以下3个函数,不会对表造成改变,故传入SqList
Status show_list(linkList);//5显示表中所有元素
Status getElem_by_local(linkList,int);//6按位置获取值
Status getIndex_by_value(linkList,ElemType);//7按值获取位置

//以下7个函数,会对表造成改变,故传入SqList*,指针
Status insert_list_by_local(linkList*,int,ElemType);//8按位置插入
Status delete_list_by_local(linkList*,int);//9按位置删除
Status delete_list_by_value(linkList*,ElemType);//10按值删除(全部删除)
Status push_elem_head(linkList*,ElemType);//11头压入元素
Status push_elem_foot(linkList*,ElemType);//12尾压入元素
Status pop_elem_head(linkList*);//13头弹出元素
Status pop_elem_foot(linkList*);//14尾弹出元素

Status union_lists(linkList*,linkList*);//15单链表的合并

//1初始化链表
Status init_list(linkList *L)
{
    /*生成一个大小为Node的头结点,并让L指向头结点*/
    *L=(linkList)malloc(sizeof(Node));
    //如果分配的这个L不存在,说明初始化失败
    if(!L){
        printf("初始化失败,请重新操作...\n");
        return ERROR;
    }
    /*初始化成功的操作*/
    (*L)->next=NULL;//将指针域置空
    printf("初始化链表成功.\n");
    return OK;
}

//2清空链表
Status clear_list(linkList *L)
{
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;//指当前结点
    linkList q;//记录下一个结点的位置
    p=(*L)->next;//指向第一个结点
    while(p){//没有达到表尾
        q=p->next;//记录下一个结点的位置,防止数据丢失
        free(p);//释放当前结点
        p=q;//将当前这个结点后移
    }
    (*L)->next=NULL;//将头结点的指针域置空
    printf("清空链表成功.\n");
    return OK;
}

//3检查表是否为空
Status check_list_isEmpty(linkList L)
{
    if(L->next){
        printf("链表不为空.\n");
        return OK;
    }else
    {
        printf("链表为空.\n");
    }
    return OK;
}

//4打印当前表的长度
Status show_list_length(linkList L)
{
    if(!L->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;//指向当前结点
    p=L->next;//指向第一个结点
    int count;
    count =0;
    while(p){
        count++;
        p=p->next;
    }
    printf("表中一共有%d个元素.\n",count);
    return OK;
}

//返回当前表的长度
int return_list_length(linkList L)
{
    if(!L->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;//指向当前结点
    p=L->next;//指向第一个结点
    int count;
    count =0;
    while(p){
        count++;
        p=p->next;
    }
    return count;
}

//5显示表中所有元素
Status show_list(linkList L)
{
    if(!L->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;
    p=L->next;//指向第一个结点
    printf("表为:");
    while(p){
        printf("%d  ",p->data);
        p=p->next;
    }
    printf("\n");
    return OK;
}

//6按位置获取值
Status getElem_by_local(linkList L,int key)
{
    if(!L->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;//指当前结点
    p=L->next;
    int i;//计数器,向后移动指针
    i=1;
    while(p&&i<key){
        p=p->next;
        i++;
    }
    if(!p||i>key){
        printf("输入的位置有误,请重新操作.\n");
        return ERROR;
    }
    printf("第%d个元素为%d.\n",key,p->data);
    return OK;
}

//7按值获取位置
Status getIndex_by_value(linkList L,ElemType value)
{
    if(!L->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;
    p=L->next;
    int i=0;
    int count=0;
    while(p){
        i++;
        if(p->data==value){
            printf("表中第%d个元素值为%d.\n",i,value);
            count++;
        }
        p=p->next;
    }
    if(count>0){
        printf("链表中一共有%d个值为%d的元素.\n",count,value);
    }
    if(count==0){
        printf("链表中找不到值为%d的元素.\n",value);
    }
    return OK;
}

//8按位置插入
Status insert_list_by_local(linkList *L,int key,ElemType value)
{
    int i;//充当计数器
    linkList p;//指当前的结点
    linkList s;//指新加入的结点,由于链表由结点构成,插入元素就是插入结点
    i=1;//从第一个结点开始找,而不是头结点
    /*
        循环成立的条件:
        1、当前结点不为NULL
        2、由于链表查找元素是通过结点一个一个地查找,需要的条件是i等于key
    */
    p=*L;//p指向头结点

    //while循环的作用:挨个向后遍历结点
    while(p&&i<key){
        p=p->next;
        i++;
    }
    /*异常处理*/
    //1、p为NULL;2、i>key
    if(!p||i>key){
        printf("输入的位置有误,请重新操作.\n");
        return ERROR;
    }
    //创建新结点
    s=(linkList)malloc(sizeof(Node));
    s->data=value;
    s->next=p->next;
    p->next=s;
    show_list(*L);
    return OK;
}

//9按位置删除
Status delete_list_by_local(linkList *L,int key)
{
    /*
        p为删除结点的前一个结点
        q为要删除的结点
    */
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }

    linkList p;
    linkList q;
    ElemType temp_elem;
    p=*L;//指定为头结点
    int i;
    i=1;
    while(p->next&&i<key){
        p=p->next;
        i++;
    }
    if(!(p->next)||i>key){
        printf("输入的位置有问题,请重新输入.\n");
        return ERROR;
    }
    /*
        找到的条件:
        p->next不为NULL
        i等于key
    */
     q=p->next;
     temp_elem=q->data;//记录将要删除的值,方便打印
     p->next=q->next;
    free(q);
    printf("第%d个元素%d删除成功.\n",key,temp_elem);
    show_list(*L);
    return OK;
}

//10按值删除(全部删除)
Status delete_list_by_value(linkList *L,ElemType value)
{
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList q;//指向要删除的结点
    linkList p;//指向要删除的前一个结点
    p=*L;//指向头结点
    int count;
    count=1;
    int sum;
    sum=0;
    //p->next达到NULL,说明是最后一个结点了,直接退出
    while(p->next){
        q=p->next;
        if(q->data==value){
            p->next=q->next;
            free(q);
            sum++;
            printf("第%d个值为%d的元素被删.\n",count,value);
        }else
        {
            p=p->next;//值不匹配,则指针向后移
        }
        count++;
    }
    if(sum==0){
        printf("链表中没有%d这个值,请重新操作...\n",value);
        return ERROR;
    }
    printf("链表中一共有%d个这样的值.\n",sum);
    show_list(*L);
    return OK;
}

//11头压入元素
Status push_elem_head(linkList *L,ElemType value)
{
    linkList p;
    p=*L;
    linkList s;
    s=(linkList)malloc(sizeof(Node));
    s->data=value;
    s->next=p->next;
    p->next=s;
    show_list(*L);
    return OK;
}

//12尾压入元素
Status push_elem_foot(linkList *L,ElemType value)
{
    linkList p;//指当前结点
    linkList s;//新产生的结点
    p=*L;
    while(p->next){
        p=p->next;
    }
    s=(linkList)malloc(sizeof(Node));
    s->data=value;
    p->next=s;
    s->next=NULL;
    show_list(*L);
    return OK;
}

//13头弹出元素
Status pop_elem_head(linkList *L)
{
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;
    p=*L;//指向头结点
    linkList q;//指当前结点
    q=p->next;
    ElemType temp_elem;
    temp_elem=q->data;
    p->next=q->next;
    free(q);
    printf("表头元素%d被弹出.\n",temp_elem);
    show_list(*L);
    return OK;
}

//14尾弹出元素
Status pop_elem_foot(linkList *L)
{
    if(!(*L)->next){
        printf("链表为空,请添加元素后再进行操作.\n");
        return ERROR;
    }
    linkList p;
    p=*L;
    linkList q;

    ElemType temp_elem;
    while(p->next){
        q=p->next;
        if(q->next==NULL){
            break;
        }
        p=p->next;
    }
    temp_elem=q->data;
    free(q);
    p->next=NULL;
    printf("表尾元素%d被弹出.\n",temp_elem);
    show_list(*L);
    return OK;
}

//15单链表的合并
Status union_lists(linkList *A,linkList *B)
{
    linkList pa;//指向头结点
    pa=*A;
    linkList pb;
    pb=*B;

    if(!(*A)->next){
        show_list(*B);
        return ERROR;
    }

    if(!(*B)->next){
        show_list(*A);
        return ERROR;
    }

    linkList cur;//指向当前结点
    while(pa->next){
        cur=pa->next;
        if(cur->next==NULL){
            break;
        }
        pa=pa->next;
    }

    cur->next=pb->next;
    return OK;
}


int main()
{
    linkList L;
    printf("请继续操作...\n");
    while(1){
        int input;
        int key;
        ElemType value;
        printf("\n==========================\n");
        printf("1、初始化链表.\n");
        printf("2、清空链表.\n");
        printf("3、检查链表是否为空.\n");
        printf("4、打印表的长度.\n");
        printf("5、打印表中所有元素.\n");
        printf("6、按位置实现查找值.\n");
        printf("7、按值实现查找位置.\n");
        printf("8、按位置实现插入.\n");
        printf("9、按位置实现删除.\n");
        printf("10、按值实现删除.\n");
        printf("11、头部压入元素.\n");
        printf("12、尾部压入元素.\n");
        printf("13、头部弹出元素.\n");
        printf("14、尾部弹出元素.\n");
        printf("15、单链表的合并.\n");
        printf("==========================\n");
        printf("请输入对应操作的序号:");
        scanf("%d",&input);
        switch(input)
        {
        case 1:
            init_list(&L);
            break;
        case 2:
            clear_list(&L);
            break;
        case 3:
            check_list_isEmpty(L);
            break;
        case 4:
            show_list_length(L);
            break;
        case 5:
            show_list(L);
            break;
        case 6:
            printf("请输入要查找的位置(K):");
            scanf("%d",&key);
            getElem_by_local(L,key);
            break;
        case 7:
            printf("请输入要查找的值(V):");
            scanf("%d",&value);
            getIndex_by_value(L,value);
            break;
        case 8:
            printf("请输入要插入的位置和值(K,V):");
            scanf("%d,%d",&key,&value);
            insert_list_by_local(&L,key,value);
            break;
        case 9:
            printf("请输入要删除的位置(K):");
            scanf("%d",&key);
            delete_list_by_local(&L,key);
            break;
        case 10:
            printf("请输入要删除的值(V):");
            scanf("%d",&value);
            delete_list_by_value(&L,value);
            break;
        case 11:
            printf("请输入要头压入的值(V):");
            scanf("%d",&value);
            push_elem_head(&L,value);
            break;
        case 12:
            printf("请输入要尾压入的值(V):");
            scanf("%d",&value);
            push_elem_foot(&L,value);
            break;
        case 13:
            pop_elem_head(&L);
            break;
        case 14:
            pop_elem_foot(&L);
            break;
        case 15:
            printf("\nTestTestTestTestTestTestTestTestTestTestTestTestTest\n");
            printf("单链表合并测试:\n");
            ElemType value_A,value_B;
            int flag;
            linkList A;
            init_list(&A);
            printf("初始化A表(使用尾插法,以1024结束):\n");
            while(1){
                scanf("%d",&value_A);
                if(value_A==1024){
                    break;
                }
                push_elem_foot(&A,value_A);
            }
            printf("A");
            show_list(A);

            linkList B;
            init_list(&B);
            printf("初始化B表(使用尾插法,以1024结束):\n");
            while(1){
                scanf("%d",&value_B);
                if(value_B==1024){
                    break;
                }
                push_elem_foot(&B,value_B);
            }
            printf("B");
            show_list(B);

            printf("ccccccccccccccccccccccccccccccccccc\n");
            printf("A");
            show_list(A);
            printf("B");
            show_list(B);
            printf("ccccccccccccccccccccccccccccccccccc\n");

            printf("\n合并之后,");

            flag=union_lists(&A,&B);

            if(flag){
                show_list(A);
            }
            printf("\nTestTestTestTestTestTestTestTestTestTestTestTestTest\n");
            break;
        default:
            printf("输入的序号有误,请重新输入...\n");
            break;
        }
    }
    return 0;
}

🚀先看后赞,养成习惯!🚀

🚀 先看后赞,养成习惯!🚀

🎈觉得文章写得不错的老铁们,点赞评论关注走一波!谢谢啦!🎈


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值