数据结构之(1)链表

引言

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。

每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。

链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。

链表有很多种不同的类型:单向链表,双向链表以及循环链表。

单向链表

概念:单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;链表是使用指针进行构造的列表;又称为结点列表,因为链表是由一个个结点组装起来的;其中每个结点都有指针成员变量指列表中的下一个结点;

列表是由结点构成,由head指针指向第一个成为表头的结点而终止于最后一个指向NULL的指针;

/**2015年2月27日16:42:27 by:我愛編程**/
/**功能:创建、插入、打印单链表(SingleLinkList--SLL)**/
#include <stdio.h>
#include <malloc.h>

//0.单链表(SLL)结点
typedef struct node
{
	char data;          //数据域
	struct node *next;  //指针域
}LNode;

//1.初始化单链表(SLL),返回链表头指针
LNode *InitSLL()
{
	//开辟头结点
	LNode *head = NULL;

	//初始化是否成功
	if ( NULL != (head = (LNode *)malloc(sizeof(LNode))) )
		head->next = NULL;

	return head;
}

//2.往单链表(SLL)中插入(Insert)结点之“头插法”
///head --- 链表头指针
///data --- 要插入的数据
int InsertNode1(LNode *head, char data)
{
	LNode *pNode1 = NULL;
	int YesNo = 0;  //默认结点开辟失败
	//结点开辟是否成功
	if ( NULL != (pNode1 = (LNode *)malloc(sizeof(LNode))) )
	{
		pNode1->data = data;
		//将结点插入链表(SLL)头部
		pNode1->next = head->next;
		head->next = pNode1;
		YesNo = 1;
	}
	return YesNo;
}

//3.打印单链表(SLL)
///head --- 链表头指针
void DisPlaySLL(LNode *head)
{
	LNode *h = head->next;

	while (NULL != h)
	{
		printf("%c ",h->data);
		h = h->next;
	}
}

int main(void)
{
	LNode *head = NULL;
	//1.初始化单链表(SLL)
	head = InitSLL();
	//2.插入结点“头插法”
	InsertNode1(head,'a');
	InsertNode1(head,'b');
	InsertNode1(head,'c');
	InsertNode1(head,'d');
	InsertNode1(head,'e');
	//3.打印单链表(SLL)
	DisPlaySLL(head);

	return 0;
}

循环链表

概念:循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

这里,我们将上述的单向链表的初始化部分稍作修改就形成了一个循环单链表。

//1.初始化循环链表(CL),返回链表头指针
LNode *InitCL()
{
	//开辟头结点
	LNode *head = NULL;

	//初始化是否成功
	if ( NULL != (head = (LNode *)malloc(sizeof(LNode))) )
	{
		//这里用“#”标记head结点
		head->data = '#';
		//将链表首尾链接起来~~~
		head->next = head;
	}

	return head;
}

(未完待续……)

参考文献:

1)百度百科,链表,http://baike.baidu.com/view/549479.htm,2015年2月27日17:22:48

2)百度百科,单向链表,http://baike.baidu.com/view/2073053.htm,2015年2月27日17:23:05

3)百度百科,循环链表,http://baike.baidu.com/view/178643.htm,2015年2月27日17:49:00

时间: 2024-10-06 01:13:42

数据结构之(1)链表的相关文章

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

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

C#数据结构-单链表

理论基础: 链表是用一组任意的存储单元来存储线性表中的数据元素. 如果结点的引用域只存储该结点直接后继结点的存储地址,则该链表叫单链表(Singly Linked List). 单链表由头引用H唯一确定.头引用指向单链表的第一个结点,也就是把单链表第一个结点的地址放在H中. C#实现: 1接口 引用线性表的接口IListDS<T> 2实现 首先,必须定义一个单链表的节点类.  1 public class Node<T> 2    { 3        private T data

数据结构实验之链表五:单链表的拆分

数据结构实验之链表五:单链表的拆分 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入N个整数顺序建立一个单链表,将该单链表拆分成两个子链表,第一个子链表存放了所有的偶数,第二个子链表存放了所有的奇数.两个子链表中数据的相对次序与原链表一致. 输入 第一行输入整数N;: 第二行依次输入N个整数. 输出 第一行分别输出偶数链表与奇数链表的元素个数: 第二行依次输出偶数子链表的所有数据: 第三行依次输出奇数子链表的所有数据. 示例输入 10 1 3 22

数据结构实验之链表三:链表的逆置

数据结构实验之链表三:链表的逆置 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入多个整数,以-1作为结束标志,顺序建立一个带头结点的单链表,之后对该单链表的数据进行逆置,并输出逆置后的单链表数据. 输入 输入多个整数,以-1作为结束标志. 输出 输出逆置后的单链表数据. 示例输入 12 56 4 6 55 15 33 62 -1 示例输出 62 33 15 55 6 4 56 12 提示 不得使用数组. 来源 示例程序 /*************

数据结构实验之链表四:有序链表的归并

数据结构实验之链表四:有序链表的归并 Time Limit: 1000MS Memory limit: 65536K 题目描述 分别输入两个有序的整数序列(分别包含M和N个数据),建立两个有序的单链表,将这两个有序单链表合并成为一个大的有序单链表,并依次输出合并后的单链表数据. 输入 第一行输入M与N的值: 第二行依次输入M个有序的整数: 第三行依次输入N个有序的整数. 输出 输出合并后的单链表所包含的M+N个有序的整数. 示例输入 6 5 1 23 26 45 66 99 14 21 28 5

【数据结构】静态链表

数据结构之静态链表实现 前言 静态链表,是一种巧妙的数据结构实现方式. 静态链表: 每个节点有一个数据域(data),用来存放有用的数据信息: 还有一个下标域(cur),用来指示下一个元素的下标位置. 我们都知道链式线性表的优势在于插入和删除元素,时间复杂度都是O(1),因为不需要像顺序存储结构的线性表那样在插入和删除时需要移动大量的元素. 而静态链表的实现就弥补了这样的不足,我们以下标的方式来代替链式结构中使用的的指针,从而达到减少时间复杂度的功能. 分析 实现静态链表 下面是代码,实现了最基

数据结构与算法-链表的基本操作---ShinPans

//链表操作:建立.插入.删除.查找.倒置.删除等基本操作 #include<stdio.h> #include<stdlib.h> typedef  struct LNode {       int data;       structLNode *next; }LNode,*Llist; LNode *creat_head();//创建一个空表 void creat_list(LNode *,int);//创建一个长度为n的线性链表 void insert_list(LNode

I学霸官方免费教程三十七:Java数据结构之单向链表结构

数据结构之单向链表 例如:现有双向链表OneWayLinked中存储着1,2,3,4四个元素,那么集合对象中会有4个节点A.B.C.D,由上述结构可以知道,节点A中存储着元素1和节点B:节点B中存储着元素2和节点C,节点C中存储着元素3和节点D,节点D中存储着元素4和null.如果现在要在元素2和3中间插入一个元素5:过程如下:1.创建节点E,E中存储元素52.将B中的下一个节点修改为节点E3.将E中的下一个节点赋值为节点C从上述过程看,插入时没有节点位置移动的操作,所以效率比较高:删除的过程和

python数据结构与算法——链表

具体的数据结构可以参考下面的这两篇博客: python 数据结构之单链表的实现: http://www.cnblogs.com/yupeng/p/3413763.html python 数据结构之双向链表的实现: http://www.cnblogs.com/yupeng/p/3413800.html 我这里只实现了单链表的类型,代码也相对精简一点: 先构造关于节点的类: 1 class Node: 2 def __init__(self,data=None,next=None): 3 self

数据结构---栈的链表实现

栈的链表实现C代码如下: #include <stdio.h> typedef int ElemType; typedef struct node { ElemType Data; struct node *next; }Node; typedef struct stack { Node *top; }Stack; //初始化栈 void InitStack(Stack *S) { S->top=NULL; } //入栈 int PushStackValue(Stack *S) { pr