数据结构-线性表之单向链表--一点一滴

单向链表

单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。

单向链表的数据结构可以分为两部分:数据域和指针域,数据域存储数据,指针域指向下一个储存节点的地址。分为动态单向链表和静态单向链表。单向链表也可以根据是否带头节点分为带头节点结构和无带头节点结构。我们把指向单链表的指针为头指针。头指针所指的不存放数据元素的第一个节点称作头节点。存放数据元素的节点成为第一个数据元素节点

注:第一个数据元素节点在带头节点单链表中是第二个节点;而在不带头节点的单链表中是第一个节点。

带头节点单链表和不带头节点单链表比较

拿出来做比较主要是因为带头节点和不带头节点单链表删除和插入操作不一样,只是对于头指针,容易出现错误。废话少说,比较内容如下:

  1. 如选用带头节点的单链表,设头指针为head,则在第一个数据元素节点前插入元素,不会改变头指针head的值,改变的是头指针所指向头节点的指针域值。即改变的是head->next的值。当临时变量p等同于head时,改变的是指针p->next的值,这与在其他元素节点前插入节点的过程相同;类似的则删除第一个数据元素节点时,不会改变头指针head的值,即改变的是head->next,当临时变量等同于head时,改变的是p->next的值。这与删除其他位置元素节点相同。
  2. 如选用不带头节点的单链表,设头指针为head,则在第一个数据元素节点前插入元素,头指针head的值将改变为等于s指针的值。(s相当于需要插入的节点元素),若在其他位置插入元素s,头指针head不会改变,改变的是临时变量p->next的值。如删除第一个元素节点时,头指针head的值改变为head->next,删除其他元素节点时,不会改变头指针head的值,改变的是临时变量p->next的值。

如果对于上面的比较有点困惑,你可以画一下原型图。head为头指针,节点s是需要插入的元素节点。p是指向你单链表插入或删除的第n-1个节点。(比如你是在第4个节点前插入,p是指向了第3个节点)。

单链表的节点定义和基本操作

  1 /********单链表的定义*******/
  2 typedef struct Node
  3 {
  4     DataType data;
  5     struct Node *next;
  6 }SLNode;
  7
  8 /*
  9  * 初始化单链表
 10  *在初始化之前头指针参数head没有具体的地址值,在初始化操作时
 11  *头指针head才得到具体的了具体的地址值,而这个地址值要返回给
 12  *调用函数,所以,此时的头指针参数head要设计成指针的指针类型
 13  *如果此时头指针类型设置为指针类型,那么调用方将无法得到在初
 14  *使化函数中被赋值的头指针参数head的数值
 15  */
 16
 17
 18  void InitiateList(SLNode **head)
 19 {
 20     *head = (SLNode *)malloc(sizeof(SLNode));
 21     (*head)->next = NULL;
 22 }
 23
 24 /*得到单链表的元素节点个数*/
 25 int GetListLength(SLNode *head)
 26 {
 27     SLNode *p = head;
 28     int size = 0;
 29     while(p->next != NULL)
 30     {
 31         p=p->next;
 32         size ++;
 33     }
 34     return size;
 35 }
 36
 37 /*在带头节点的单链表head的第i个(0<=i<=size)节点插入一个数据元素为x的节点*/
 38 int InsertListNode(SLNode *head,int i,DataType x)
 39 {
 40     SLNode *p,*q;
 41     p = head;
 42     int j = -1;
 43     while(p->next != NULL && j<i-1)
 44     {
 45         p = p->next;
 46         j++;
 47     }
 48     if(j != i-1)
 49     {
 50         printf("Insert Position is error\n");
 51         return 0;
 52     }
 53     q = (SLNode *)malloc(sizeof(SLNode));
 54     q->data = x;
 55     q->next = p->next;
 56     p->next = q;
 57     return 1;
 58 }
 59
 60 /*删除带头节点单链表的第i个节点(0<= i<=size-1)
 61  * 被删除节点的数据域值由x带回,删除成功返回1失败
 62  * 返回0
 63  */
 64
 65 int DeleteListNode(SLNode *head,int i,DataType *x)
 66 {
 67     SLNode *p,*q;
 68     p = head;
 69     int j = -1;
 70     while(p->next != NULL && p->next->next != NULL && j<i-1)
 71     {
 72         p=p->next;
 73         j++;
 74     }
 75     if(j != i-1)
 76     {
 77         printf("Error\n");
 78         return 0;
 79     }
 80     q = p->next;
 81     *x = q->data;
 82     p->next = p->next->next;
 83     free(q);
 84     return 1;
 85 }
 86
 87 /* 取数据元素*/
 88 int GetListNode(SLNode *head,int i,DataType *x)
 89 {
 90     SLNode *p;
 91     p = head;
 92     int j = -1;
 93     while(p->next != NULL && j<i)
 94     {
 95         p=p->next;
 96         j++;
 97     }
 98     if(j != i)
 99     {
100         printf("error\n");
101         return 0;
102     }
103     *x = p->data;
104     return 1;
105 }
106
107 /* 撤销单链表*/
108 void DestroyList(SLNode **head)
109 {
110     SLNode *p,*q;
111     p = *head;
112     while(p != NULL)
113     {
114         q = p;
115         p = p->next;
116         free(q);
117     }
118     *head = NULL;
119 }

单链表的实例

建立一个单链表,首次输入1,2,3,4,5,6,,7,8,9,10元素节点,然后删除元素5的节点。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 typedef int DataType;
 5 #include "SLNode.h"
 6 int main(void)
 7 {
 8     SLNode *head;
 9     int i = 0,temp;
10     InitiateList(&head);
11     for(i=0;i<10;i++)
12     {
13         InsertListNode(head,i,i+1);
14     }
15     DeleteListNode(head,4,&temp);
16     printf("It will delete node value is %d\n",temp);
17     for(i=0;i<GetListLength(head);i++)
18     {
19        GetListNode(head,i,&temp);
20        printf("%d\t",temp);
21     }
22     printf("\n");
23     DestroyList(&head);
24     return 0;
25 }

时间: 2024-10-19 11:06:20

数据结构-线性表之单向链表--一点一滴的相关文章

c/c++ 线性表之单向链表

c/c++ 线性表之单向链表 线性表之单向链表 不是存放在连续的内存空间,链表中的每个节点都指向下一个节点,最后一个节点的下一个节点是NULL. 真实的第一个节点是头节点,头节点不存放数据,单纯为了编写程序方便.但是下面注释里写的[第一个节点]的含义是头节点的下一节点,也就是真实存放数据的第一个节点. 下面的代码实现了以下功能 函数 功能描述 push_back 从链表的最后插入节点 push_front 从链表的起始插入节点 show_list 打印出链表里每个节点的值 pop_back 删除

[大话数据结构]线性表之单链表结构和顺序存储结构

线性表定义: 零个或者多个数据元素的有限序列.元素之间是有顺序的,如果元素存在多个,则第一个元素无前驱,最后一个元素无后继.其他每个元素都有且只有一个前驱和后继.并且数据元素的类型要相同. 线性表的抽象数据类型: ADT 线性表(List) Data 线性表的数据对象集合为{a1,a2,...,an},每个元素的类型均为DataType. 其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素. 数据元素之间的关系是一对一的关系.

Java数据结构-线性表之单链表LinkedList

线性表的链式存储结构,也称之为链式表,链表:链表的存储单元可以连续也可以不连续. 链表中的节点包含数据域和指针域,数据域为存储数据元素信息的域,指针域为存储直接后继位置(一般称为指针)的域. 注意一个头结点和头指针的区别: 头指针: 指向链表的第一个节点的指针,若链表有头结点,则是指向头结点的指针: 头指针具有标识作用,所以常用头指针作为链表的名字: 不论链表是否为空,头指针都不为空: 是链表的必要元素. 头结点: 头结点是为了操作的统一和方便而设立的,放在第一个元素节点的前面,其数据域一般无意

线性表之单向链表的基本操作实现

这篇文章用来回顾单向链表的相关知识并实现如下几个操作: 初始化 插入 删除 逆置 销毁 且实现的链表为带头节点的单线非循环链表.由于链表在尾插入时需要遍历到链表的最后一个位置,所以我需要记住最后一个节点的位置,为此,本文会简单的实现一个单向链表的类. 0.链表的定义与类中提供的API 1 typedef int ELEMENT; 2 3 struct Node_s { 4 Node_s():data(),NEXT(nullptr){} 5 ELEMENT data; 6 Node_s * NEX

Java数据结构-线性表之静态链表

静态链表的定义: 节点由一个一维数组和一个指针域组成,数组用来存放数据元素,而指针域里面的指针(又称游标)用来指向下一个节点的数组下标.这样的链表称之为静态链表. 链表中的数组第一个和最后一个位置需要特殊处理,不存数据.第一个位置(即数组0下标)的节点的指针用来存放备用链表的第一个节点的数组下标.最后一个位置(即数组长度MaxSize-1下标)的节点的指针用来存放指向有数值的第一个数据元素的数组下标,类似于单链表的头结点. 静态链表的示例图: 下面举一个摘抄自<大话数据结构>的例子,来解释一下

[数据结构]线性表之单链表的类模板实现

类的具体实现如下: ///////////////////////// #include"LinearList.h" #include <iostream> #include <cstdlib> using namespace std; template<class T> struct LinkNode //链表节点类 { T data; LinkNode<T>* link; LinkNode(LinkNode<T>* ptr

[考研系列之数据结构]线性表之链表

1.链表分类 通过线性表概述,我们知道了链表这样一种数据结构,它又分成三类,分别是 单向链表 循环链表 双向链表 单向链表 单向链表的指针域只有一个指向下一个节点的指针,需要注意几点: 1.头指针--指向第一个节点 2.最后一个结点的指针指向NULL 3.头结点--在链表的第一个结点之前附设一个结点,它的数据域为空 所以,我们看到:  单向链表为空的<=>链表有且只有一个头结点<=>头结点的指针指向NULL 循环链表 循环链表和单向链表最大的不同就是:最后一个结点的指针不再指向NU

数据结构线性表链表的C语言实现

                                                                                      数据结构线性表链表的C语言实现      说明:线性表是一种最简单的线性结构,也是最基本的一种线性结构,所以它不仅是学习中的重点,也是应用开发非常常用的一种数据结构.它可以分为顺序表和链表.它的主要操作是数据元素的插入,删除,以及排序等.接下来,本篇文章将对线性表链表的基本操作和运用进行详细的说明(包含在源代码的注释中),并给

数据结构&gt;&gt;线性表【注意】--&gt;链表求A-B(原A与B都递增,求完的A-B不改变A原来的顺序)

/*关于链表的题目 * A.B是两个递增有序的单链表,元素个数分别是m和n,求 * 集合A-B,并将结果保存在A中,且仍然保持递增有序. * converge_ab */ #include <iostream.h> using namespace std; typedef struct lnode{ int data; struct lnode * next; }lnode; int main(){ lnode * create_chain(int num,int interval,int s