• 单链表


    建立链表结点的结构体有关链表问题,我折腾了好长时间,总是断断续续的。如果想统一花一点时间攻克,估计也差不多能攻克了,折腾来折腾去,拖延症一犯,到现在也没有完全弄清楚。现在先把自己搞明白的有关链表的内容搞明白。

    说起单链表,有以下几个方面的内容需要你会写。

    1. 建立单链表。

    要想实现对链表的操作,首先的当然是建立链表啦。没有链表怎么进行插入删除查找操作啊。

    建立单链表有以下几个部分

    • 建立链表结点的结构体。
    • 为结点分配空间
    • 为结点赋值
    • 为结点确定位置

    以下是建立的链表结点的结构体

    1 typedef struct Node
    2 {
    3     int element;
    4     struct Node *next;
    5 }node;

    其次是创建链表的函数了:

    /********************************
    *描述:创建链表
    *参数:无
    *返回值:链表头指针
    *******************************/
    node *creat()
    {
        node *head, *p, *q;
        int x = 0;
        bool cycle = true;
        head = (node*)malloc(sizeof(node));
        p = head;
        while (cycle)
        {
            printf("请输入一个整数");
            scanf("%d", &x);
            if (x != 0)
            {
                q = (node*)malloc(sizeof(node));
                q->element = x;
                p->next = q;
                p = q;
            }
            else
                cycle = false;
        }
        head = head->next;
        p->next = NULL;
        return head;
    }

    创建链表时候尤为注意几点:1:为结点分配空间。2:为结点赋值3:为结点确定位置。

    node *head;
    head = creat();

    在主函数当中,用这两句,就能轻松调用创建链表的函数进行使用了。

    还有几个小函数,不是很关键,但是学学还是很有用的,没准什么时候就能用到,看下面。

    /********************************
    *描述:测量链表长度
    *参数:head:链表头指针
    *返回值:链表长度
    *******************************/
    int flength(node *head)
    {
        int count = 1;
        node *p;
        p = head;
        while (p->next != NULL)
        {
            ++count; 
            p = p->next;
        }
        return count;
    }
    /********************************
    *描述:打印链表
    *参数:head:链表头指针
    *返回值:链表长度
    *******************************/
    void fprint(node *head)
    {
        int length = flength(head);
        node *pdata = head;
        for (int i = 0; i < length; ++i)
        {
            printf("第%d个元素的值为%d", i, pdata->element);
            pdata = pdata->next;
        }
    }

    2.删除元素

    删除元素中涉及到一些技巧,注意一下。

    /********************************
    *描述:删除链表中的某个元素
    *参数:head:链表头指针
    *      num:要删除的数据
    *返回值:链表头
    *******************************/
    node *fdelete(node *head, int num)
    {
        node *p1, *p2;
        p1 = head;
        p2 = head;
        while (num != p1->element&&p1->next != NULL)
        {
            p2 = p1;
            p1 = p1->next;
        }
        if (num == p1->element)//删除的元素是头结点还是非头结点要分别对待。
        {
            if (p1 == head)
            {
                head = p1->next;
                free(p1);
            }
            else
            {
                p2->next = p1->next;
                free(p1);
                p1 = NULL;// 写这句的目的是不能让p1成为悬空指针。
            }
    
        }
        else
            printf("找不到要删除的元素!!!");
    }

    搜寻整个链表,找寻某个值是否存在于链表之中

    /********************************
    *描述:查询某元素
    *参数:head:链表头
    *      num:要查询的数据
    *返回值:无
    *******************************/
    void fsearch(node *head, int num)
    {
        node *p1;
        p1 = head;
        while (p1->element != num&&p1->next != NULL)
        {
            p1 = p1->next;//找寻下面一个链表结点是否符合条件
        }
        if (p1->element == num)
        {
            printf("%d值已经找到了",num);
        }
        else
        {
            printf("搜遍整个链表,此值不存在");
        }
    }

    插入一个链表的操作,现在看来已经非常简单了。

    /********************************
    *描述:插入一个数,插入数据的原则为从小到大
    *参数:head:链表头
    *       num:插入的数据
    *返回值:链表头
    *******************************/
    node* finsert(node *head, int num )
    {
        node *p0,*p1, *p2;
        p1 = p2 = head;//给予指针初始位置
        p0->element = num;
        while (p0->element >= p1->element)
        {
            p1 = p1->next;
            p2->next = p1;
        }
        if (p1 == head)
        {
            p0->next = p1;
            head = p0;
        }
        else if (p1->next != NULL)
        {
            p2->next = p0;
            p0->next = p1;
        }
        else
        {
            p1->next = p0;
            p0->next = NULL;
        }
        return head;
    }

    用链表实现冒泡排序和一般数组的冒泡排序没什么差别

    /********************************
    *描述:链表冒泡排序,从大到小
    *参数:head:链表头
    *返回值:无
    *******************************/
    void fsort(node *head)
    {
        node *q;
        int len = flength(head);
        for (int i = 0; i < len; ++i)
        {
            for (q = head; q->next != NULL; q = q->next)
            {
                if (q->element < q->next->element)
                {
                    int temp;
                    temp = q->element;
                    q->element = q->next->element;
                    q->element = temp;
                }
            }
        }
    }

    用链表实现逆序排序

    /********************************
     *描述:链表逆置
     *参数:head:表头
     *返回值:node:返回新的链表头
     *******************************/
    node *freverse(node *head)
    {
        node *p0=NULL,*p1=NULL,*p2=NULL;  
        
        if(flength(head)<=1){
            printf("
    链表节点至少为2");
            return NULL;
        }
        else{
            p1=head;
            p2=p1->next;
            while(p2!=NULL){         //一定要用p2判断,否则错误
                p0=p2->next;
                p2->next=p1;
                p1=p2;
                p2=p0;            
            } 
            head->next=NULL;
            head=p1;
            printf("
    链表逆置完成");
            return head;
        }
    }
    逆序排序这里可以重点说一下。一般而言,建立一个链表结点,结点的指针和其中的值是不会轻易分离的。p2->next=p1; 只是p2指向的下一个结点发生的改变,但是p2->element并没有发生改变。这一点上花了不短的时间才能理解清楚,不容易。
  • 相关阅读:
    [LeetCode] Best Time to Buy and Sell Stock with Transaction Fee 买股票的最佳时间含交易费
    Visual Studio Many Projects in One Solution VS中多工程开发
    [LeetCode] 713. Subarray Product Less Than K 子数组乘积小于K
    [LeetCode] Minimum ASCII Delete Sum for Two Strings 两个字符串的最小ASCII删除和
    [LeetCode] Erect the Fence 竖立栅栏
    3D Slicer Reconstruct CT/MRI
    [LeetCode] Partition to K Equal Sum Subsets 分割K个等和的子集
    [LeetCode] Degree of an Array 数组的度
    [LeetCode] Count Binary Substrings 统计二进制子字符串
    [LeetCode] Max Area of Island 岛的最大面积
  • 原文地址:https://www.cnblogs.com/chengxuyuanxiaowang/p/3948356.html
Copyright © 2020-2023  润新知