一、概念
- 线性表:多个数据元素组成的有限序列。
- 链表:线性表的链式存储结构
二、分类
1.单链表
- 概念: 链表的结点包含数据域和指针域,指针域只有一个,并指向下一个结点。
- 特点:插入删除数据的时间复杂度仅为O(1),不需要预分配存储空间。
2. 循环链表
- 概念:单链表中,终端结点的指针由空指针改为指向头结点的指针,形成一个环。
- 特点:相对于单链表,循环链表可以在任意位置开始访问到整个链表,尾指针的存在方便了链表的合并。
3. 双向链表
- 概念:结点中除数据域以外包含两个指针域,一个指向前驱结点,一个指向后继结点。
- 特点:相对于单项链表可以实现双向的查找。
三、单链表
注:C语言实现,包括单链表的创建、增加数据、查询某一个数据、删除某个结点、获取链表长度等。
/**
* singly_linked_list.c
*
* Created on: 2020年1月27日
* Author: Beyonderwei
*/
/*----------单链表----------*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 定义链表元素所存储的数据类型
typedef int ElemType;
// 定义节点的存储结构
typedef struct Node
{
/* data */
ElemType data;
struct Node *next;
}Node;
// 定义链表指针
typedef struct Node *LinkList;
/**
* Function 创建带有头节点的单链表,即创建一个头节点
* @param:
* list: 链表
* @return 指向链表的指针
*/
LinkList createList(void)
{
LinkList list;
list = (LinkList)malloc(sizeof(Node));
list->next = NULL;
return list;
}
/**
* Function 向链表追加数据
* @param:
* list: 链表
* elem: 要追加的数据
* @return 指向链表的指针
*/
LinkList listAppend(LinkList list, ElemType elem)
{
LinkList tmp, node;
tmp = list;
while(tmp->next)
{
tmp = tmp->next;
}
node = (LinkList)malloc(sizeof(Node)); //生成一个新的节点,来存储数据
node->data = elem;
node->next = NULL;
tmp->next = node;
return list;
}
/**
* Function 按照条件查找链表中的某个元素
* @param:
* list: 链表
* elem: 要查找的数据
* @return 指向该结点的指针
*/
LinkList getElem(LinkList list, ElemType elem)
{
LinkList tmp = list;
while(tmp)
{
if(tmp->data == elem) // 可以改为按照data中的某个条件来查找
{
return tmp;
}
else
{
tmp = tmp->next;
}
}
return NULL;
}
/**
* Function 获取链表的长度
* @param:
* list: 链表
* @return 链表的长度(不包括头节点)
*/
unsigned int getLength(LinkList list)
{
unsigned int length = 0;
LinkList tmp;
tmp = list;
while(tmp->next)
{
length++;
tmp = tmp->next;
}
return length;
}
/**
* Function 按照条件删除链表的某一个结点
* @param:
* list: 链表
* elem: 要删除的元素
* @return list: 删除成功
* NULL: 删除失败
*/
LinkList deleteElem(LinkList list, ElemType elem)
{
LinkList last_node;
LinkList tmp = list;
while(tmp->next)
{
last_node = tmp;
tmp = tmp->next; //因为头结点没有存储数据,直接略过
if(tmp->data == elem)
{
last_node->next = tmp->next;
free(tmp);
return list;
}
}
return NULL;
}
/*---------测试代码----------*/
void main(void)
{
LinkList list;
unsigned int length;
list = createList();
LinkList e;
listAppend(list, 1);
listAppend(list, 2);
listAppend(list, 3);
listAppend(list, 4);
listAppend(list, 5);
listAppend(list, 6);
deleteElem(list, 7);
deleteElem(list, 5);
length = getLength(list);
printf("链表长度为:%d\n",length);
e = getElem(list, 6);
if(e != NULL)
{
printf("查询的值为:%d\n",e->data);
}
printf("链表第一个元素:%d",list->next->data);
}
四、循环链表与双向链表
对于以上功能的实现仅仅是在单项链表上做了一些改变。
Email : Beyonderwei@Gmail.com
Website : http://beyonderwei.com
WeChat: