C语言数据结构:实现单链表的诸多功能(头插法,尾插法,查找,增添,删除,替换,排序,释放)

实现单链表的诸多功能(头插法,尾插法,查找,增添,删除,替换,排序,释放)

直接上代码喽,其中的注释很详细的呢!

#include<stdio.h>
#include<stdlib.h>
typedef struct node 
{
    int data;
    struct node* next;
} Node;     //创建结构体 struct node 别名Node

/*
头插法:创建指针函数creat1()
*/
Node* creat1(int x)
{
    int e;
    Node* head, * p;  //头指针head,新结点指针p
    head = (Node*)malloc(sizeof(node)); //申请表头存储空间
    head->next = NULL; //表头指针域置为NULL
    printf("请输入%d个任意整数:\n", x);
    /*
    采用for循环给已知结点个数申请空间,并使结点之间相连
    */
    for (int i = 0; i < x; i++)
    {
        p = (Node*)malloc(sizeof(node));
        scanf_s("%d", &e);
        p->data = e;
        p->next = head->next;
        head->next = p;
}
    return head;// 单链表返回值(表头结点)head
}
/*
尾插法:创建指针函数creat2();
*/
Node* creat2(int x)
{
    int e;
    Node* head, * p, * q;//头指针head,并使p指针也指向表头,q指针是最后遍历单链表输出数据时要用
    head = (Node*)malloc(sizeof(node));
    q = head;
    q->next = NULL; //初始表头结点指针域置为空
    printf("请输入%d个任意整数:\n", x);
    /*
    采用for循环给已知结点个数申请空间,并使结点之间相连
    */
    for (int i = 0; i < x; i++)
    {
        p = (Node*)malloc(sizeof(node));
        scanf_s("%d", &e);
        p->data = e;
        q->next = p;
        q = p;
    }
    q->next = NULL;
    return head;// 单链表返回值(表头结点)head
}
/*
当在主函数中选用功能1时(头插法),调用此函数
*/

void output1(int n)  
{
    Node* creat1(int x);      //声明单链表头插法函数
    void find(int m, Node * pb);//声明查找函数
    void replace(int m, Node * pb);//声明替换函数
    void insert(int m, Node * pb);//声明插入函数
    void cancle(int m, Node * pb);//声明删除函数
    void sort1(int m, Node * pb);//声明排序函数(从大到小)
    void sort2(int m, Node * pb);//声明排序函数(从小到大)
    void clean(Node*pb);//声明释放内存函数
    Node* pt = creat1(n);//调用单链表头插法函数,并将返回值head赋给pt
    Node* pl = pt;  //这里设置指针pl是方便实行单链表其他的功能(实参)
    /*
    指针pt遍历单链表输出数据
    */
    pt = pt->next;
    printf("头插法单链表输出数字顺序为:\n");
    for (int i = 0; i < n; i++)
    {
        printf("%d ", pt->data);
        pt = pt->next;
    }
    find(n, pl);//调用查找函数
    replace(n, pl);//调用替换函数
    insert(n, pl);//调用插入函数
    cancle(n,pl);//调用删除函数
    sort1(n,pl);//调用排序函数(从大到小)
    sort2(n, pl);//调用排序函数(从小到大)
    clean(pl);//调用释放内存函数
}
/*
当在主函数中选用功能2时(尾插法),调用此函数
*/

void output2(int n) 
{
    Node* creat2(int x);//声明单链表尾插法函数
    void find(int m, Node * pb);//声明查找函数
    void replace(int m, Node * pb);//声明替换函数
    void insert(int m, Node * pb);//声明插入函数
    void cancle(int m, Node * pb);//声明删除函数
    void sort1(int m, Node * pb);//声明排序函数(从大到小)
    void sort2(int m, Node * pb);//声明排序函数(从小到大)
    void clean(Node*pb);//声明释放内存函数
    Node* pt = creat2(n);//调用尾插法函数,并把函数的返回值head赋给pt
    Node* pl = pt;  //这里设置指针pl是方便实行单链表其他的功能
/*
指针pt遍历链表输出数据
*/
    pt = pt->next;
    printf("头插法单链表输出数字顺序为:\n");
    for (int i = 0; i < n; i++)
    {
        printf("%d ", pt->data);
        pt = pt->next;
    }
    find(n, pl);//调用查找函数
    replace(n, pl);//调用替换函数
    insert(n, pl);//调用插入函数
    cancle(n, pl);//调用删除函数
    sort1(n, pl);//调用排序函数(从大到小)
    sort2(n, pl);//调用排序函数(从小到大)
    clean(pl);//调用释放空间函数
}
/*
查找链表中固定位置数据
*/
void find(int m,Node*pb)
{
    int i;
    int j = 0;
    printf("\n请输入你想查询的的位置(范围:1-%d):\n",m);
    scanf_s("%d", &i);
    if (i > 0 && i <= m)
    {
        while (i!=j)
        {
            pb = pb->next;
            j++;
        }
        printf("查询正确:%d", pb->data);
    }
    else printf("你输入的数字不在范围:(1-%d),查询失败",m);
}
/*
链表中数据的替换
*/
void replace(int m,Node*pb)
{
    int j=0;
    int i,e;
    Node* pc = pb;//创建指针pc也指向表头结点,用指针pb查找指定位置进行替换,用pc指针遍历链表输出替换后数据
    printf("\n请输入你要替换的位置(范围:1-%d):\n", m);
    scanf_s("%d",&i);
    if (i > 0 && i <= m)
    {
        while (i != j)
        {
            pb = pb->next;
            j++;
        }
        printf("请输入你想要替换的数字:\n");
        scanf_s("%d",&e);
        pb->data = e;
        printf("替换数据成功,输出链表结果为:\n");
        pc = pc->next;
        for (int j=0;j<m;j++)
        {
            printf(" %d ", pc->data);
            pc= pc->next;
        }
    }
    else printf("你要替换的位置不在范围:(1-%d)内\n", m);
}
/*
链表中插入数据
*/
void insert(int m,Node*pb)
{
    int i,e;
    int j = 1;
    Node* pc = pb;//创建指针pc指向表头结点,指针pb查找插入位置,并进行插入,指针pc遍历单链表输出插入后的数据
    Node* p;
    printf("\n请输入你要插入的位置(范围:1—%d):\n",m+1);
    scanf_s("%d",&i);
    if (i >= 1 && i <= m + 1)
    {
        while (pb && i != j)
        {
            pb = pb->next;
            j++;
        }
        p = (Node*)malloc(sizeof(node));
        printf("请输入你要插入的数据:\n");
        scanf_s("%d",&e);
        p->data = e;
        p->next = pb->next;
        pb->next = p;
        printf("插入数据成功,输出链表结果:\n");
        pc = pc->next;
        while (pc!=NULL)
        {
            printf("%d ",pc->data);
            pc = pc->next;
        }
    }
    else printf("\n你要插入的位置不在范围(范围:1—%d)",m+1);
}
/*
单链表指定位置删除
*/
void cancle(int m, Node* pb)
{
    int i;
    int j = 0;
    /*
    创建指针pc,p都指向表头结点:
         指针pc,pb是用来查找删除位置,并进行删除指定位置结点之后对结点进行连接
         指针p是用来遍历单链表输出删除后数据
    */
    Node* pc = pb;
    Node* p = pb;
    printf("\n请输入你要删除数据的位置 (范围:1-%d):\n", m + 1);
    scanf_s("%d", &i);
    if (i >= 1 && i <= m + 1)
    {
        while (j != i - 1)
        {
            pc = pb->next;
            pb = pc;
            j++;
        }
        pc = pb->next;
        pb->next = pc->next;
        free(pc);
        printf("数据清除成功,输出链表结果:\n");
        while (p->next)
        {
            p = p->next;
            printf("%d ", p->data);
        }
    }
    else printf("你删除的位置不在范围(范围:1—%d)\n", m + 1);
}
/*
单链表排序(冒泡法:效率高)
*/

void sort1(int m, Node* pb)//从大到小排序
{
    int i, j, n;
    Node* pc=pb;//指针pc指向表头结点
    
    for (i = 0; i < m - 1; i++)
    {
        for (j = 0; j < m-i-1; j++)
        {
            pc=pc->next;
            if (pc->data < pc->next->data)
            {
                n = pc->next->data;
                pc->next->data = pc->data;
                pc->data = n;
            }
        }
        pc = pb;
    }
    pb = pb->next;
    printf("\n单链表从大到小的顺序为:\n");
    for (i=0;i<m;i++)
    {
        printf("%d ",pb->data);
        pb = pb->next;
    }
}

void sort2(int m, Node* pb)//从小到大排序
{
    int i, j, n;
    Node* pc = pb;//指针pc指向表头结点

    for (i = 0; i < m - 1; i++)
    {
        for (j = 0; j < m - i - 1; j++)
        {
            pc = pc->next;
            if (pc->data > pc->next->data)
            {
                n = pc->next->data;
                pc->next->data = pc->data;
                pc->data = n;
            }
        }
        pc = pb;
    }
    pb = pb->next;
    printf("\n单链表从小到大的顺序为:\n");
    for (i = 0; i < m; i++)
    {
        printf("%d ", pb->data);
        pb = pb->next;
    }
}
/*
链表释放(需要两个指针)
*/
void clean(Node*pb)
{
    Node* pc = pb;//指针pc指向表头结点
    while (pb!=NULL)
    {
        pc = pb->next;
        free(pb);
        pb = pc;
    }
    printf("\n单链表存储空间已释放\n");
}
/*
主函数
*/
int main()
{
    int m;
    int n;
    void output1(int n);//声明头插法中诸多功能函数
    void output2(int n);//声明尾插法中诸多功能函数
    printf("\n1.头插法建立链表\n2.尾插法建立链表\n");
    printf("\n请输入选择操作的数字:\n");
    scanf_s("%d", &m);
    printf("请输入你要输入数字的个数:\n");
    scanf_s("%d", &n);
    /*
    功能判断:
         如果m=1,调用   头插法中诸多功能函数
         如果m=2,调用   尾插法中诸多功能函数
    */
    if (m == 1) output1(n);
    if (m == 2) output2(n);
    return 0;

运行的结果:

猜你喜欢

转载自www.cnblogs.com/shuqingsong/p/12640617.html