《数据结构》2.3单链表(single linked list)

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

说明:
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个节点,结束。

时间: 2024-10-13 00:51:26

《数据结构》2.3单链表(single linked list)的相关文章

PHP数据结构之实现单链表

学习PHP中,学习完语法,开始尝试实现数据结构,今天实现单链表 <?php class node //节点的数据结构 { public $id; public $name; public $next; public function __construct($id,$name) //构造函数 { $this->id=$id; $this->name=$name; $this->next=null; } } class linklist //链表的数据结构 { private $he

数据结构学习之单链表基本操作

数据结构学习之单链表基本操作 0x1 前言 今天实验课,学习了下单链表的写法,这里记录下. 0x2 正文 题目要求如下: 本实验的单链表元素的类型为char,完成如下实验要求: (1)初始化单链表h (2)采用尾插法依次插入a.b.c.d.e (3)输出单链表h (4)输出单链表h的长度 (5)判断单链表h是否为空 (6)输出单链表h的第3个元素 (7)输出元素a的逻辑位置 (8)在第4个元素位置上插入元素f (9)输出单链表h (10)删除单链表h的第3个元素 (11)输出单链表h (12)释

数据结构之_单链表的实现

数据结构之_单链表的实现 1.基本概念 链式存储定义 为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息. 单链表 线性表的链式存储结构中,每个节点中只包含一个指针域,这样的链表叫单链表. 通过每个节点的指针域将线性表的数据元素按其逻辑次序链接在一起(如图). 概念解释: 表头结点 链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息 数据结点 链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息

【数据结构】顺序存储单链表

数据结构之单链表的顺序存储实现 闲来无事,回顾下以前学过的数据结构,写个玩玩,理论的东西就不多说了,网上一搜一大堆: 重要的是需要掌握这种数据结构的思想,整个数据结构这门课最重要的也是思想! 下面是代码: //====================================================================== // // Copyright (C) 2014-2015 SCOTT // All rights reserved // // filename:

厦门大学数据结构期末考试单链表问题

因为过几天要去参加厦门大学的夏令营,提前刷了下厦门大学往年的期末考试试卷. 卷中有这么一道题目: 有一个单链表,其结点的元素值以递增顺序排列,给出数据结构,并编写一个算法删除该单链表中元素值相同的结点. 算法如下: 从头到尾扫描单链表,若当前结点和后继结点的值不相同,则指针后移,若相同,则删除该后继结点. 1 #include "stdio.h" 2 3 typedef struct Node{ 4 int data; 5 struct Node *next; 6 }Node, *Li

数据结构基础(8) --单链表的设计与实现(1)之基本操作

链表简介 数组的缺点: 1.元素插入:除了在数组的末尾插入元素之外,在数组的其他任何位置插入元素都需要进行数组元素的频繁移动(插入位置之后的元素都需往后移动), 时间复杂度约为O(N); 2.数组的删除:除了在数组的末尾删除元素之外,在数组的其他任何位置删除元素都需要进行数组元素的频繁移动(删除位置之后的元素都需往前移动), 时间复杂度也为O(N); 链表的特点: 由于在链表中插入/删除元素都不需要进行数据的移位, 只需要O(1)时间完成, 因此链表适用于频繁插入与删除的情况; 但是链表也有缺点

【C语言数据结构】循环单链表

CircleLinkList.h #ifndef CIRCLE_LINK_LIST #define CIRCLE_LINK_LIST //链表节点 typedef struct _CircleLinkListNode {     struct _CircleLinkListNode *next; }CircleLinkListNode; //循环单链表 typedef void CircleLinkList; /*  * 创建循环单链表  * @return 返回循环单链表的指针  */ Cir

【C语言数据结构】静态单链表

StaticLinkLinst.h #ifndef STATIC_LINKLIST_H #define STATIC_LINKLIST_H typedef void StaticLinkListNode;    //静态单链表节点 typedef void StaticLinkList;        //静态单链表 /*  * 创建静态单链表  * @param capacity 静态单链表的最大容量  * @return 返回静态单链表的指针  */ StaticLinkList* Stat

C++ 数据结构学习二(单链表)

模板类 //LinkList.h 单链表#ifndef LINK_LIST_HXX#define LINK_LIST_HXX#include <iostream>using namespace std; template<class T>struct Node{ T data; Node * next;}; template<class T>class LinkList{ public: LinkList(); //无参构造函数,建立只有头结点的空链表 LinkList

数据结构 线性表—单链表

本文只要实现单链表的初始化.插入(尾插.头插.任意位置插入).删除(尾删.头删.删除指定元素).查找等. 定义单链表 typedef int DataType; typedef struct LinkNode {  DataType data;  struct LinkNode *next; }LinkNode, *pLinkNode, *pList; 实现单链表的所有接口: void InitLinkList(pList* pHead);//单链表的初始化 void Destroy(pList