目录
1.单链表的基本概念
(1)单链表:当链表中的每个结点只含有一个指针域时,称为单链表。
(2)头指针:如上图所示,链表中第一个结点的存储位置叫做头指针。
(3)头结点:头结点是放在第一个元素结点之前的结点,头结点不是链表中的必须元素,其数据域一般无意义,(有些情况下会存放链表的长度,或用作监视哨等),本文的头结点存放了链表的长度。有了头结点后,对在第一个元素结点前插入结点和删除第一个结点,其操作与对其它结点的操作统一了。
(4)首元结点:就是第一个元素的结点,它是头结点后边的第一个结点。
2.单链表的基本操作
(1)初始化:给链表添加一个头结点。
(2)逆置链表:将单链表所有元素逆置。
(3)链表遍历:打印出链表的长度,并按顺序打印所有元素。
(4)查找:获取指定位置的元素。
(5)元素插入:在指定位置插入元素。
(6)元素删除:删除指定位置的元素。
(7)删除链表:将链表删除。
(8)头插法创建链表:用头插法插入一系列元素,创建链表。
(9)尾插法创建链表:用尾插法插入一系列元素,创建链表。
(10)快慢指针:利用快慢指针法的原理,快速查找一个长度未知的链表的中间结点。
这些操作中,链表逆置具有一定的难度,其基本的设计思想是:将以前的旧链表中的每个元素从旧链表中删除,并用头插法插入新的链表中。
快慢指针的设计也非常巧妙,快指针运动速度是慢指针的两倍,因此快指针指向最后一个结点的时候,慢指针刚好指向中间结点。
3.单链表编程实现----C语言
在C语言中函数和数据是分开的,每个函数都需要考虑链表的数据传递问题,这大大加大了编程的难度。
(1)链表的头文件 linklist.h
#ifndef LINKLIST_H
#define LINKLIST_H
typedef int ElemType;
typedef struct Node
{
ElemType data;
struct Node *Next;
}Node;
typedef Node* linklist;//给节点指针取别名
typedef enum Bool
{
FALSE,TRUE//枚举默认值从0开始,依次加1
}Bool;
Bool InitList(linklist* L);//初始化链表,给链表添加一个头结点
Bool GetElem(linklist L, int i, ElemType* e);//获得第i个位置的元素
Bool ListInsert(linklist* L,int i,ElemType e);//在第i个位置插入元素
Bool ListDelete(linklist* L,int i,ElemType* e);//删除第i个元素
Bool ListDeleteAll(linklist* L);//删除全部链表
void traverseList(linklist L);//遍历链表
void CreateListHead(linklist* L,int n);//头插法创建链表
void CreateListEnd(linklist* L,int n);//尾插法创建链表
void Reverse(linklist* L);//逆置链表
int findMiddle(linklist L, ElemType* e);//查找中间结点,将查找的元素值赋给e,并返回该节点是第几个结点,如果是空表则返回0
#endif // LINKLIST_H
(2)链表的源文件linklist.c
#include "linklist.h"
#include <stdio.h>
Bool GetElem(linklist L, int i, ElemType* e)
{
linklist p=L;
int j;
for(j=1;j<=i;j++)
{
p=p->Next;
if(p==NULL)
return FALSE;
}
*e=p->data;
return TRUE;
}
Bool ListInsert(linklist* L,int i,ElemType e)
{
linklist p=