zoukankan      html  css  js  c++  java
  • c语言单向链表

    一、链表概述  

      链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一个“头指针”变量,以head表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。因此,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
            链表的各类操作包括:学习单向链表的创建、删除、  插入(无序、有序)、输出、  排序(选择、插入、冒泡)、反序等等。
    二、链表创建、删除、插入等如下,将函数与声明定义进行分离为.h和.c:

    2.1 linklist.h

     1 #pragma once
     2 typedef struct list
     3 {
     4     int data;//数据域
     5     struct list *next;//指针域
     6 }LinkList;
     7 LinkList *crate_list();    //建立一个节点
     8 void traverse(LinkList*ls);//循环遍历链表
     9 LinkList* insert_list(LinkList* ls, int n, int data);//在指定位置插入元素
    10 int delete_list(LinkList* ls, int n);//删除指定位置元素
    11 int count_list(LinkList* ls);//返回链表元素的个数
    12 void clear_list(LinkList *ls);//清空链表,只保留首节点
    13 int empty_list(LinkList *ls);//返回链表是否为空
    14 LinkList *local_list(LinkList*ls, int n);//返回链表指定的位置节点
    15 LinkList * elem_list(LinkList* ls, int data);//返回指定位置data
    16 int elem_pos(LinkList *ls, int data);//返回数据域等于DATA的位置
    17 LinkList *last_list(LinkList *ls);//得到链表的最后一个节点
    18 void merge_list(LinkList * s1,LinkList* s2);//合并两个链表
    19 void reverse_lsit(LinkList *ls);//链表反转

    2.2  linklist.c

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include "linlist.h"
      4 //建立一个节点
      5 LinkList * crate_list()
      6 {
      7     return (LinkList*)calloc(sizeof(LinkList),1);
      8 }
      9 //循环遍历链表
     10 void traverse(LinkList * ls)
     11 {
     12     LinkList *p = ls;
     13     while (p)
     14     {
     15         printf("%d
    ",p->data);
     16         p = p->next;
     17     }
     18 
     19 }
     20 //插入元素
     21 LinkList * insert_list(LinkList * ls, int n, int data)
     22 {
     23     LinkList *p = ls;
     24     while (p&&n--)
     25     {
     26         p = p->next;
     27     }
     28     if (p==NULL)
     29     {
     30         return NULL;//n的位置大于链表节点数
     31     }
     32     LinkList *node = crate_list();//新建一个节点
     33     node->data = data;
     34     node->next = p->next;
     35     p->next = node;
     36     return node;
     37 }
     38 //删除节点
     39 int delete_list(LinkList * ls, int n)
     40 {
     41     LinkList *p = ls;
     42     while (p&&n--)
     43     {
     44         p = p->next;
     45     }
     46     if (p==NULL)
     47     {
     48         return -1;
     49     }
     50     LinkList *tmp = p->next;
     51     p->next = p->next->next;
     52     free(tmp);
     53     return 0;
     54 }
     55 //返回链表元素的个数
     56 int count_list(LinkList * ls)
     57 {
     58     LinkList *p = ls;
     59     int count = 0;
     60     while (p)
     61     {
     62         count++;
     63         p = p->next;
     64     }
     65     return count;
     66 }
     67 //清空链表,只保留首节点
     68 void clear_list(LinkList * ls)
     69 {
     70     LinkList* p = ls->next;
     71     while (p)
     72     {
     73         LinkList * tmp = p->next;
     74         free(p);
     75         p = tmp;
     76     }
     77     ls->next = NULL;//只有首节点,则首节点next实则为NULL
     78 }
     79 //返回聊表是否为空
     80 int empty_list(LinkList * ls)
     81 {
     82     if (ls->next)
     83         return 0;
     84     else
     85         return -1;
     86     return 0;
     87 }
     88 //返回链表指定位置的节点数据域
     89 LinkList * local_list(LinkList * ls, int n)
     90 {
     91     LinkList* p = ls;
     92     while (p&&n--)
     93     {
     94         p=p->next;
     95     }
     96     if (p == NULL)
     97         return NULL;
     98     return p;
     99 }
    100 //返回指定位置数据域对应的节点
    101 LinkList * elem_list(LinkList * ls, int data)
    102 {
    103     LinkList*p = ls;
    104     while (p)
    105     {
    106         if (p->data = data)
    107             return p;
    108         p = p->next;
    109     }
    110     return NULL;//没有找到
    111 }
    112 //返回数据域等于data的节点位置
    113 int elem_pos(LinkList * ls, int data)
    114 {
    115     LinkList * p = ls;
    116     int index = 0;
    117     while (p)
    118     {
    119         index++;
    120         if (p->data = data)
    121             return index;
    122         p = p->next;
    123     }
    124     return -1;//没有找到索引
    125 }
    126 
    127 LinkList * last_list(LinkList * ls)
    128 {
    129     LinkList * p = ls;
    130     while (p->next)
    131     {
    132         p = p->next;
    133     }
    134     return p;
    135 }
    136 //合并两个链表,将结构放在第一个链表中
    137 void merge_list(LinkList * s1, LinkList * s2)
    138 {
    139     //合并连标点节点,不合并链表头
    140     last_list(s1)->next = s2->next;
    141     free(s2);
    142 }
    143 
    144 void reverse_lsit(LinkList * ls)
    145 {
    146     if (ls->next == NULL)
    147         return;//只有只有一个头节点
    148     if (ls->next->next == NULL)
    149         return;
    150     LinkList * last = ls->next;//ls->next为最后一个节点
    151     LinkList * pre = ls;//上一个节点的指针
    152     LinkList *cur = ls->next;//当前节点
    153     LinkList*next = NULL;//下一个节指针
    154     while (cur)
    155     {
    156         next = cur->next;
    157         cur->next = pre;
    158         pre = cur;
    159         cur = next;
    160     }
    161     ls->next = pre;
    162     last->next = NULL;
    163 }

    2.3  测试主函数

     1 #include<stdlib.h>
     2 #include<stdio.h>
     3 #include"linlist.h"
     4 #define Len 10
     5 int main()
     6 {
     7     LinkList *first = crate_list();//创建第一个节点
     8     LinkList *second = crate_list();//创建第二个节点
     9     LinkList *third = crate_list();//创建第三个节点
    10     first->next = second;//指针域第一个节点的指针指向下一节点
    11     second->next = third;//指针域第二个节点的指针指向下一节点
    12     third->next = NULL;//指针域第三个节点的指针指向下一节点,只有三个元素,所以下一节点为NULL
    13     first->data = 1;//数据域第一个元素
    14     second->data = 2;//数据域第二个元素
    15     third->data = 3;//数据域第二个元素
    16     //遍历链表
    17     printf("插入前:
    ");
    18     traverse(first);//遍历头即可打印整个链表,因为链表是靠指针连接在一起
    19     insert_list(first,0,100);
    20     printf("插入后:
    ");
    21     traverse(first);
    22     printf("删除后
    ");
    23     delete_list(first,2);
    24     traverse(first);
    25     printf("--------------------------------------
    ");
    26     printf("链表的个数cout=%d
    ", count_list(first));
    27     //printf("清空链表,直保留首节点
    ");
    28     //clear_list(first);
    29     printf("链表的个数cout=%d
    ", count_list(first));
    30     printf("%d
    ",local_list(first,2)->data);
    31     printf("data=%d
    ",last_list(first)->data);
    32     printf("-----------------------------------------
    ");
    33 
    34     LinkList * pp = crate_list();
    35     for (int i = 0; i < Len; i++)
    36     {
    37         insert_list(pp,0,i);
    38     }
    39     merge_list(first,pp);
    40     traverse(first);
    41     printf("xxxxxxxxxxxxxxxxxxxx");
    42     reverse_lsit(first);
    43     traverse(first);
    44     return 0;
    45 }

    2.4 结果显示:

  • 相关阅读:
    用JLabel显示时间-- JAVA初学者遇到的一个困难
    linux下观看b站视频,解决字体乱码
    fedora21 codeblocks在编辑装态下无法输入
    fedora21安装无线驱动
    Hdu 1053 Entropy
    linux下的压缩解压命令 tar 的简单描述
    表的截断、删除、创建
    列的维护
    非分区表的重组
    创建高效且易于管理的表以及表的管理和维护
  • 原文地址:https://www.cnblogs.com/506941763lcj/p/11442498.html
Copyright © 2011-2022 走看看