单向链表 c语言实现

  • 定义(引用百度百科)
    单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
  • 场景
  • 在实际生产中,有可能在软件启动后,对一些数据进行多态扩容,比如,网卡收发包的时候,从协议栈上产生一个需求的包,需要暂时排队,等网卡把数据发送出去后,在在队列里处理,所以这种利用堆中分散的内存,以结点为单位的数据结果是有一定的意义的。

    1. C语言实现,聊作记录
      链表的数据的数据结构

      typedef struct node
      {
          int data;                                           //数据域
          struct node *next;                          //指针域
      }NODE_t;

      链表的创建

      NODE_t *CreatNodeList()
      {
      NODE_t *head = NULL;
      
      head = (NODE_t *)malloc(sizeof(NODE_t));
      if(!head)
          exit(-1);
      head->next = NULL;
      
      return head;
      }

    链表的插入,头插入,有个头节点,方便遍历,处理

    int InsertNode(NODE_t *head,int data)
    {
        NODE_t *cur = NULL;
    
        if(!head)
            exit(-1);
    
        cur = (NODE_t *)malloc(sizeof(NODE_t));
        if(!cur)
            exit(-1);
    
        cur->data = data;
        //cur 插入到 head 和 head->next 之间
        cur->next = head->next;
        head->next = cur;
    
        return 0;
    }

    结点的查找

    NODE_t *findNode(NODE_t *head,int data)
    {
        head = head->next;
        while(head)
        {
            if(head->data == data)
            {
                break;
            }
            head = head->next;
        }
        if(head == NULL)
        {
            printf("sorry,%d is not in the list\n",data);
        }
    
        return head;
    }

    结点的删除

        int DeleteNodeOfList(NODE_t *head,NODE_t *pfind)
    {
        // 首先找到这个需要删除指针的前一个节点的指针
        // 因为pfind 的合法性在外面判断,此处不再判断
        while(head->next != pfind)
        {
            head = head->next;
        }
    
        head->next = pfind->next;
        free(pfind);
        pfind = NULL;
    
        return 0;
    }

    这里的删除,假设结点数目很多,则会造成一个问题,单链表只能一个方向,则需要找到需要删除的节点的前驱指针,则需要从头开始遍历,比较浪费资源,所以,这个地方存在优化空间,就是,一旦拥有需要删除的节点,则可以这么操作

    • 将需要删除节点后驱结点的数据域数据拷贝至当前的删除节点数据域
    • 删除删除节点的后驱指针

    优化版本如下:

    // 优化点: 不必每次都遍历所有的节点,找到前驱节点
    // 将这个需要删除的节点的后驱节点的数据域拷贝过来,然后删除这个后驱节点
    int DeleteNodeOfList_Better(NODE_t *head,NODE_t *pfind)
    {
        NODE_t *p = pfind->next;
    
        //最后一个节点,它其后没有后驱节点,所以需要从头遍历,找到它的前置节点
        if(pfind->next == NULL)
        {
            while(head->next != pfind)
            {
                head = head->next;
            }
    
            head->next = pfind->next;
            free(pfind);
            pfind = NULL;
        }
        else //对于除最后一个节点的外的其他位置节点,则使用覆盖后删除后置节点的方式实现删除
        {
    
            pfind->data = pfind->next->data;
            pfind->next = pfind->next->next;
    
            free(p);
            p = NULL;
        }
    
        return 0;
    }

    一旦找到结点的指针操作只是针对数据域的一个操作,比较便捷
    结点的修改

    int UpdateNode(NODE_t *head,int olddata,int newdata)
    {
        NODE_t *p = findNode(head,olddata);
        if(p)
        {
            p->data = newdata;
        }
    
        return 0;
    }

    遍历打印显示

    void showList(NODE_t *head)
    {
        head = head->next;
        while(head)
        {
            printf("%d ==> ",head->data);
            head = head->next;
        }
        printf("end..\n");
    }

    链表的排序

    int sortList(NODE_t *head)
    {
        int i = 0,j = 0;
        int listlen = 0;
        int tmpData = 0;
        NODE_t *p = NULL;
    
        // 使用冒泡排序,不动指针域,比较数据域,使用临时变量,将有大小之别的节点的数据域交换
        // 得到链表长度,方便冒泡
        listlen = ListNodeLen(head);
    
        // 指到首节点
        p = head->next;
        for(i = 0;i < listlen-1;i++)
        {
            // 每一轮从头开始
            p = head->next;
            for(j = 0;j<listlen - i-1;j++)
            {
                // 将小值排在前面
                if(p->data > p->next->data)
                {
                    tmpData = p->data;
                    p->data = p->next->data;
                    p->next->data = tmpData;
                }
                p = p->next;
            }
        }
    
        return 0;
    }

    原文地址:http://blog.51cto.com/6306331/2073431

    时间: 2024-10-29 03:33:19

    单向链表 c语言实现的相关文章

    写给过去的自己-No.1-数据结构篇-单向链表C语言的实现

    过去的自己,你好.     今天我来教你单向链表,不知道你何时会看到这篇文章,也不知道你此刻对C语言的掌握,我会尽可能讲解细一点.     讲链表之前我先讲一下数组.相信你不管怎样肯定用过数组对吧,数组就是一种数据的组织形式,特点是所有的数据在逻辑上是顺序摆放的,通过数组名和数组下标 就可以找到某个元素,而且在内存中存放的物理地址也是连续的,定义数组时,一旦中括号中的数字确定了,数组中元素个数也就确定了.那么问题来了,因为数组 的大小需要提前确定,所以定义数组时必须统计好程序中用了多少元素,用多

    C语言之字符单向链表

    /* * @Author: suifengtec * @Date:   2017-09-02 16:06:33 * @Last Modified by:   suifengtec * @Last Modified time: 2017-09-02 20:47:13 **/ /* 字符单向链表 gcc -o a.exe main.c && a  */ #include <stdio.h> #include <stdlib.h> #include <stdbool

    C语言反转单向链表的代码

    学习过程中中,把内容过程中常用的内容片段做个珍藏,下边内容段是关于C语言反转单向链表的内容,应该能对大伙有较大用处. #include "stdafx.h" enum{N = 3};class Node{public:int var;Node(int i):pNext(NULL), var(i){}}; {if(pHead->pNext->pNext != NULL)helper(pHead->pNext, reverseHead);elsereverseHead =

    C语言之单向链表

    1,单向链简洁.单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始:链表是使用指针进行构造的列表:又称为结点列表,因为链表是由一个个结点组装起来的:其中每个结点都有指针成员变量指列表中的下一个结点:?列表是由结点构成,由head指针指向第一个成为表头的结点而终止于最后一个指向nuLL的指针: 2,例子要求:根据示例代码中的例子,完成单向链表(single linked list)中的以字符串为数据的链表的插入.删除以及查找,并支持单向链表的反转:

    C语言实现简单的单向链表(创建、插入、删除)及等效STL实现代码

    实现个算法,懒得手写链表,于是用C++的forward_list,没有next()方法感觉很不好使,比如一个对单向链表的最简单功能要求: input: 1 2 5 3 4 output: 1->2->5->3->4 相当于仅仅实现了插入.遍历2个功能(当然遍历功能稍微修改就是销毁链表了) 用纯C写了份测试代码 /* 基本数据结构的定义以及函数的声明 */ typedef int ElemType; typedef struct Node { ElemType elem; struc

    C语言:创建动态单向链表,创建完成后,输出每一个节点的数据信息。

    // //  main.c //  dynamic_link_list // //  Created by ma c on 15/8/5. //  Copyright (c) 2015年 bjsxt. All rights reserved. //  要求:写一个函数建立有3名学生数据的动态单向链表,并输出链表中每个结点的所有内容. /* 建立动态链表的思想: 1.开辟一个新结点,并使p1,p2指向它: 2.读入一个学生数据给p1所指的结点: 3.head = NULL,n = 0; 4.判断读

    C语言学习之单向链表操作

    该文件为单向链表操作的一些接口:(如发现有错误的地方,及时告知,不胜感激!) list.h #ifndef  _CHAINLIST_H_ #define  _CHAINLIST_H_ typedef struct { char key[15]; char name[20]; int age; }DATATYPE_T; typedef struct Node { DATATYPE_T  data; struct Node *next; }chainListType; /* 添加节点到链表末尾 */

    C语言实现单向链表及其各种排序(含快排,选择,插入,冒泡)

    #include<stdio.h> #include<malloc.h> #define LEN sizeof(struct Student) struct Student //结构体声明 { long num; int score; struct Student* next; }; int n; struct Student* creat() //创建单向链表 { struct Student *head=NULL, *p_before, *p_later; p_before =

    C语言 单向链表

    1.单向链表的定义 struct student { char name[10]; float score; struct student *next; }; next作为同类型指针,指向与它所在节点一样的节点. 2.单向链表的基本操作 1)建立链表 int main() { /*定义结构指针,pnew指向新节点,head指向头节点,tail指向尾节点*/ struct student *pnew, *head, * ptail; /* 动态分配库函数malloc,分配长度为sizeof(str