zoukankan      html  css  js  c++  java
  • 《数据结构》2.3单链表(single linked list)

      1 //单链表节点的定义
      2 typedef struct node
      3 {
      4     datatype data;
      5     struct node *next;
      6 }LNode,*LinkList;            //LNode是节点类型,LinkList是指向LNode类型节点的指针类型
      7 LinkList H;                    //定义头指针变量
      8 
      9 //建立单链表(时间复杂度均为O(n))
     10 //逆序建立单链表(头插法)
     11 LinkList Creath_LinkList()
     12 {
     13     Linklist L = NULL;        //空表
     14     LNode *s;
     15     int e;                    //设数据元素的类型为int
     16     scanf("%d", &e);
     17     while(e != flag)        //flag为设置的线性表数据元素结束标志
     18     {
     19         s = malloc(sizeof(LNode));
     20         s->data = e;
     21         s->next = L;
     22         L = s;
     23         scanf("%d", &e);
     24     }
     25     return L;
     26 }
     27 //顺序建立单链表(尾插法)
     28 LinkList Creatr_LinkList()
     29 {
     30     LinkList L = NULL;
     31     LNode *s, *r = NULL;
     32     int e;                    //设数据元素的类型为int
     33     scanf("%d", &e);
     34     while(e != flag)        //flag为设置的线性表数据元素结束标志
     35     {
     36         s = malloc(sizeof(LNode));
     37         s->data = e;
     38         if(L == NULL) L = s;//插入的节点是第一个节点
     39         else r->next = s;    //插入的节点是其他节点
     40         r = s;                //r恒指向新的节点
     41         scanf("%d", &e);
     42     }
     43     if(r != NULL) r->next = NULL;//对于非空表,尾部节点的指针于置为空指针
     44     return L;
     45 }
     46 
     47 //求表长(时间复杂度均为O(n))
     48 //设L是不带头节点的单链表
     49 int length_LinkList1(LinkList L)
     50 {
     51     LNode *p = L;
     52     int i;                    //i是计数器
     53     if(p == NULL) return 0; //空表的情况
     54     i = 1;                    //在非空表的情况下,p所指的是第一个节点
     55     while(P->next)
     56     {
     57         p = p->next; i++;
     58     }
     59     return i;
     60 }
     61 //设L是带头节点的单链表(引入头节点概念,在后面的算法中若不加额外说明则都认为单链表是带头节点的)
     62 int length_LinkList2(LinkList L)
     63 {
     64     LNode *p = L;            //p指向头节点
     65     int i = 0;                //i是计数器
     66     while(P->next)
     67     {
     68         p = p->next; i++;    //p所指的正是第i个节点
     69     }
     70     return i;
     71 }
     72 
     73 //查找操作(时间复杂度均为O(n))
     74 //按序号查找
     75 LNode *Getc_LinkList(LinkList L, int i) //在单链表L中查找第i个节点,找到则返回其指针,否则返回空
     76 {
     77     LNode *p = L;            //L为头节点
     78     int j = 0;
     79     while(p->next != NULL && j<i)
     80     {
     81         p = p->next; j++;
     82     }
     83     if(j == i) return p;
     84     else return NULL;
     85 }
     86 //按值查找
     87 LNode *Locate_LinkList(LinkList L,datatype e) //在单链表L中查找值为e的节点,找到后返回其指针,否则返回空
     88 {
     89     LNode *p = L->next;         //L为头节点
     90     while(p != NULL && p->data != e)
     91         p = p->next;
     92     return p;
     93 }
     94 
     95 //插入操作
     96 //在某节点之后插入节点(将*s插入*p的后面,时间复杂度为O(1))
     97 s->next = p->next;
     98 p->next = s;                //这两条指令顺序不能改变,否则会使链表断开
     99 //在某节点之前插入节点(将*s插入*p的前面,时间复杂度为O(n))
    100 q = L;
    101 while(q->next != p)
    102     q = q->next;            //查找*p的直接前驱*q
    103 s->next = q->next;
    104 q->next = s;
    105 //定位插入(把数据域值为e的节点插入链表中作为第i个节点,时间复杂度为O(n))
    106 int Insert_LinkList(LinkList L, int i, datatype e) //在链表的第i个位置上插入值为e的元素
    107 {
    108     LNode *p, *s;
    109     p = Get_LinkList(L, i-1); //查找第(i-1)个节点
    110     if(p == NULL)
    111     {
    112         printf("参数i错"); return 0; //第(i-1)个节点不存在,不能插入
    113     }
    114     else
    115     {
    116         s = malloc(sizeof(LNode)); //申请节点
    117         s->data = e;
    118         s->next = p->next;        //新节点插入在第(i-1)个节点的后面
    119         p->next = s;
    120         return 1;
    121     }
    122 }
    123 
    124 //删除操作
    125 //删除指针指向单链表中的节点
    126 //(1)删除*p(时间复杂度为O(n))
    127 q->next = p->next;            //设查找到*p的直接前驱为*q
    128 free(p);
    129 //(2)删除*p的直接后继节点,假设其存在(时间复杂度为O(1))
    130 s = p->next;                //设*p的直接后继节点为*s
    131 p->next = s->next;
    132 free(s);
    133 //删除单链表L的第i个节点(时间复杂度为O(n))
    134 int Del_LinkList(LinkList L, int i) //删除单链表上L的第i个节点
    135 {
    136     LinkList p, s;
    137     p = Get_LinkList(L, i-1); //查找第(i-1)个节点
    138     if(p == NULL)
    139     {
    140         printf("第i个节点不存在"); return -1;
    141     }
    142     else
    143     {
    144         if(p->next == NULL)
    145         {
    146             printf("第i个节点不存在"); return 0;
    147         }
    148         else
    149         {
    150             s = p->next;        //s指向第i个节点
    151             p->next = s->next;  //从链表中删除s
    152             free(s);            //释放s
    153             return 1;
    154         }
    155     }
    156 }
    View Code

    说明:
    1.顺序建立单链表
            由于第一个节点加入时原链表为空,它作为链表的第一个节点是没有直接前驱节点的,所以它的地址就是整个链表的起始地址,该值需要放在链表的头指针变量中;而后面再插入的其他节点都有直接前驱节点,其地址只需放入直接前驱节点的指针域即可。
    2.头节点
            为了统一操作,在链表的头部加入一个特殊节点,即头节点;头节点的类型与数据节点的类型一致,标识链表的头指针变量L中存放的是头节点的地址,那么即使是空表,头指针L也不为空(其中存放着头节点的地址);将头节点看作链表第一个节点的直接前驱,那么链表的第一个节点也有直接前驱,则无须再对第一个节点进行额外操作;
            头节点的加入使得“空表”和“非空表”的处理成为一致,其数据域无定义,指针域存放的是第一个数据节点的地址。

    算法思路:
    1.求表长
            设一个指针变量p和计数器i,初始化后,如果p所指节点后面还有节点,p向后移动,计数器i同时加1,直至p指向表尾。可以从单链表不带头节点和带头节点两个角度出发来设计算法(注意:计算线性表的长度时不包括头节点)。
    2.查找操作
        1)按序号查找:从链表的第一个节点起,判断当前节点是否是第i个节点,若是,则返回该节点的指针,否则,根据指针域寻找下一个节点,直到表结束为止。若没有找到第i个节点,则返回空。
        2)按值查找:从链表的第一个节点起,判断当前节点数据域的值是否等于e,若等于,则返回该节点的指针,否则,根据指针域寻找下一个节点,直到表结束为止。若表中没有节点数据域的值等于e,则返回空。
    3.插入操作(定位插入)
        (1)寻找第i个节点的直接前驱第(i-1)个节点,若存在,则继续第(2)步,否则结束;
        (2)申请新节点,并为其数据域赋值为e;
        (3)将新节点作为第(i-1)个节点的直接后继插入单链表中,结束。
    4.删除操作(删除单链表L的第i个节点)
        (1)寻找第(i-1)个节点;若存在,则继续第(2)步,否则结束;
        (2)若存在第i个节点,则继续第(3)步,否则结束;
        (3)删除第i个节点,结束。

    亲爱的读者:如果觉得本文对你有所帮助,请点击推荐,分享给其他人!
  • 相关阅读:
    可左右拖动窗口demo
    制作一个简单的百度网盘在线视频加速的chrome插件
    git分支
    使用git的ssh
    git的概念和常用命令
    爬虫:获取页面 -- request库的使用
    字符串方法
    从实现原理更深入了解call和apply
    Git和GitHub使用
    localStorage和sessionStorage
  • 原文地址:https://www.cnblogs.com/zhuangwei/p/5692174.html
Copyright © 2011-2022 走看看