• C语言 单链表的基本操作(增删改查)


      这是尾插法单链表,单链表比较适合用来做队列和栈,因为在链表的头和尾时的增删改查的时间复杂度为O(1),而在链表内部的增删改查的平均时间复杂度为O(n)。

    #include "stdio.h"
    #include "stdlib.h"      //提供malloc()和free()
    #include "string.h"
    #include "time.h"        //提供strcpy(),time()等
    
    //1.用结构体创建链表节点
    //一个用来存放数据,另一个存放指针
    struct Node
    {
        int data;             //数据域
        struct Node* next;    //指针域(指向节点的指针)
    };
    
    //2.全局定义链表头尾指针,方便调用
    struct Node* head = NULL;
    struct Node* end = NULL;
    
    //3.向链表添加数据
    void AddListTill(int a )
    {
        //创建一个节点
        struct Node* temp = (struct Node*)malloc(sizeof(struct Node));  //此处注意强制类型转换
    
        //节点数据进行赋值
        temp->data = a;
        temp->next = NULL;
    
        //连接分两种情况1.一个节点都没有2.已经有节点了,添加到尾巴上
        if(NULL == head)
        {
    
            head = temp;
            //end=temp;
        }
        else
        {
            end->next=temp;
            //end=temp;   //尾结点应该始终指向最后一个
        }
        end=temp;  //尾结点应该始终指向最后一个
    }
    
    //4.遍历链表并输出
    void ScanList()
    {
        struct Node *temp = head;        //定义一个临时变量来指向头
        while (temp != NULL)
        {
            printf("%d
    ",temp->data);
            temp = temp->next;        //temp指向下一个的地址 即实现++操作
        }
    
    }
    
    //5.查找指定的数据是否在链表内
    struct Node* FindNode(int a )
    {
        struct Node *temp = head;
    
        while(temp != NULL)
        {
        if(a == temp->data)
        {
            return temp;
        }
        temp = temp->next;
        }
        //没找到
            return NULL;
    } 
    
    //6.删除链表
    void FreeList()
    {
        struct Node *temp = head;        //定义一个临时变量来指向头
        while (temp != NULL)
        {
            struct Node* pt = temp;
            temp = temp->next;        //temp指向下一个的地址 即实现++操作
            free(pt);                 //释放当前
        }
        //头尾清空,不然下次的头就接着0x10
        head = NULL;
        end = NULL;
    }
    
    //7.在指定位置处插入数据
    void AddListRand(int index,int a)
    {
    
        if (NULL == head)
        {
            printf("链表没有节点
    ");
            return;
        }
        struct Node* pt = FindNode(index);
        if(NULL == pt)    //没有此节点
        {
            printf("没有指定节点
    ");
            return;
        }
        //有此节点
        //创建临时节点,申请内存
        struct Node* temp =(struct Node *)malloc(sizeof(struct Node));
        //节点成员进行赋值
        temp->data = a;
        temp->next = NULL;
        //连接到链表上 1.找到的节点在尾部 2.找到的节点在中间
        if (pt == end)
        {
            //尾巴的下一个指向新插入的节点
            end->next = temp;
            //新的尾巴
            end = temp;
        }
        else
        {
            //先连后面 (先将要插入的节点指针指向原来找到节点的下一个)
            temp->next = pt->next;
            //后连前面
            pt->next = temp;
        }
    
    }
    
    //8.删除链表末尾数据
    void DeleteListTail()
    {
        if (NULL == end)
        {
            printf("链表为空,无需删除
    ");
            return;
        }
        //链表不为空
        //链表有一个节点
        if (head == end)
        {
            free(head);
            head = NULL;
            end = NULL;
        }
        else
        {
            //找到尾巴前一个节点
            struct Node* temp = head;
            while (temp->next != end)
            {
                temp = temp->next;
            }
            //找到了,删尾巴
            //释放尾巴
            free(end);
            //尾巴迁移
            end=temp;
            //尾巴指针为NULL
            end->next = NULL;
        }
    
    }
    
    //9.删除链表的第一个数据
    void DeleteListHead()
    {   //记住旧头
        struct Node* temp = head;
        //链表检测
        if (NULL == head)
        {
            printf("链表为空
    ");
            return;
        }
    
        head = head->next;  //头的第二个节点变成新的头
        free(temp);
    
    }
    
    //10.删除链表指定的数据
    void DeleteListRand(int a)
    {
    
        //链表判断 是不是没有东西
        if(NULL == head)
        {
            printf("链表没东西
    ");
            return;
        }
        //链表有东西,找这个节点
        struct Node* temp = FindNode(a);
        if(NULL == temp)
        {
            printf("查无此点
    ");
            return;
        }
        //找到了,且只有一个节点
        if(head == end)
        {
            free(head);
            head = NULL;
            end = NULL;
        }
        else if(head->next == end) //有两个节点
        {
            //看是删除头还是删除尾
            if(end == temp)
            {
                DeleteListTail();
            }
            else if(temp == head)
            {
                DeleteListHead();
            }
        }
        else//多个节点
        {
            //看是删除头还是删除尾
            if(end == temp)
                DeleteListTail();
            else if(temp == head)
                DeleteListHead();
            else //删除中间某个节点
            {    //找要删除temp前一个,遍历
                struct Node* pt = head;
                while(pt->next != temp)
                {
                    pt=pt->next;
                }
                //找到了
                //让前一个直接连接后一个 跳过指定的即可
                pt->next = temp->next;
                free(temp);
    
            }
        }
    }
    
    //主函数
    void main()
    {
        struct Node *pFind;
        
        srand((unsigned)time(NULL));
        int i;
        //创建20个节点
        for(i = 0; i < 20; i++)
            AddListTill(i);    //添加数据
            //AddListTill(rand());
    
        AddListRand(4,86);      //在指定位置4增加节点14
        //DeleteListHead();     //删除一个头结点
        //DeleteListTail();     //删除一个尾结点
        DeleteListRand(4);      //删除4节点
        ScanList();             //遍历输出链表
        //FreeList();           //删除链表
        
        pFind = FindNode(5);    //查找5节点
    
        if (pFind !=  NULL)
        {
            printf("找到%d
    ",pFind->data);    //找到节点并且输出该节点数据
        }
        else
        {
            printf("No Find!
    ");
        }
    
    }

      以下是排序算法的时间和空间复杂度表:

  • 相关阅读:
    上传图片并实现本地预览
    a标签传递参数
    HTTP错误 404.17–Not Found 请求的内容似乎是脚本,因而将无法有静态文件处理程序来处理
    VM虚拟机无法拖拽、粘贴、复制
    ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值
    Oracle中Clob类型处理解析:ORA-01461:仅可以插入LONG列的LONG值赋值
    Oracle获取表结构信息:表名、是否视图、字段名、类型、长度、非空、主键
    SQLServer2005,2000获取表结构:字段名、类型、长度、主键、非空、注释
    c# float和double的“坑”
    VS活动解决方案平台
  • 原文地址:https://www.cnblogs.com/qingsong/p/14165262.html
Copyright © 2020-2023  润新知