单链表
//线性表的单链存储结构
typedef int EleType;
typedef struct Node
{
EleType data;
struct Node *next;
}Node;
//定义LinkList
typedef struct Node *LinkList;
//单链表的读取
//获取链表第i个元素的算法思路:声明一个指针p指向链表的第一个结点,初始化j从1开始;当j<i时,遍历链表,让p的指针向后移动,不断的指向下一个结点,j累加1;若到链表末尾p为空,则说明第i个结点不存在;否则查找成功,返回结点p的数据。
//初始条件:1<=i<=ListLength
Status GetNodeElem(LinkList L, int i, EleType *e)
{
int j;
LinkList p;
p = L->next;
j = 1;
while (p && j < i)
{
p = p->next;
j++;
}
if (!p || j > i)
return ERROR;
*e = p->data;
return OK;
}
//单链表的插入
//单链表第i个元素插入结点算法思想:声明一个指针p指向链表头结点,初始化j从1开始;当j<i,遍历链表,让j不断向后移动,j+1;若到链表末尾p为空,则说明第i个结点不存在;否则查找成功,在系统中生成一个空结点s;将数据元素e赋值给s->data;单链表的插入标准语句s->next=p->next,p->next=s;返回成功。
Status InsToLink(LinkList *L, int i, EleType e)
{
LinkList p,s;
int j;
p = *L;
j = 1;
while (p && j<i)
{
p = p->next;
j++;
}
if (!p || j>i)
return ERROR;
//生成新结点
s = (LinkList)malloc(sizeof(Node));
s->data = e;
s->next = p->next;
p->next = s->next;
return OK;
}
//单链表的删除
//单链表第i个元素删除的算法思路:声明p指向表头指针,初始化j从1开始;当j<i,遍历链表,让p向后移动,不断的指向下一个指针,j++;若到末尾p为空,则说明第i个结点不存在;否则查找成功,将欲删除的结点p->next赋值给q;单链表标准删除语句,p->next = q->next;将q中数据赋值给e,作为返回;释放q结点;返回成功
Status DelLinkNode(LinkList *L, int i, EleType *e)
{
LinkList p, q;
p = *L;
int j;
j = 1;
while (p->next && j < i)
{
p = p->next;
j++;
}
if (!(p->next) || j>i)
return ERROR;
q = p->next;
p->next = q->next;
*e = q->data;
//让系统回收此节点,释放内存
free(q);
return OK;
}
//单链表的整表创建
//创建单链表的过程就是一个动态生成链表的过程
//单链表整表创建算法思路:声明一个指针p和计数器变量i;初始化一个空链表L;让L的头结点指针指向null,即创建一个带头结点的单链表;循环:生成一个新结点赋值给p,随机生成一个数字赋值给p的数据域p->data;将p插入到头结点与前一新节点之间。
//头插法
void CreateListHead(LinkList *L,int n)
{
LinkList p;
int i;
//初始化随机数种子
srand(time(0));
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL;
for (i = 0; i < n; i++)
{
p = (LinkList)malloc(sizeof(Node));
p->data = rand() % 100 + 1;
p->next = (*L)->next;
(*L)->next = p;
}
}
//尾插法
void CreateListTail(LinkList *L,int n)
{
LinkList p, r;
int i;
r = (*L);
for (i = 0; i < n; i++)
{
p = (LinkList)malloc(sizeof(Node));
p->data = rand() % 100 + 1;
r->next = p;
r = p;
}
r->next = NULL;
}
//单链表的整表删除
//单链表的整表删除的算法思路:声明一个节点p和q;将第一个结点赋值给p;循环:将下一个结点赋值给p;释放p;将q赋值给p;
Status ClearList(LinkList *L)
{
LinkList p, q;
p = (*L)->next;
while (p)
{
q = p->next;
free(p);
p = q;
}
(*L)->next = NULL;
return OK;
}
//单链表结构和顺序存储结构的优缺点:
//存储分配方式:顺序存储结构用一段连续的存储单元依次存储线性表的数据元素;单链表采用链式存储结构,用一组任意的存储樊元存放线性表的元素。
//时间性能:1.查找:顺序存储结构O(1),单链表O(n);2.插入和删除:顺序存储结构需要平均移动表长一样的元素,时间为O(n),单链表在线出某位置指针后,插入和删除时间仅为O(1)
//空间性能:顺序存储结构需要预分配存储空间,分大了浪费,分小了上溢;单链表存储结构不需要分配存储空间,只要有就可以分配,元素个数也不受限制
静态链表
#define MAXSIZE 1000
typedef struct
{
ElemType data;
int cur;
}Component,StaticLinkList[MAXSIZE];
Status InitList(StaticLinkList space)
{
int i;
for (i = 0; i < MAXSIZE - 1;i++)
{
space[i].cur = i + 1;
}
space[MAXSIZE-1].cur = 0;
return OK;
}
int Malloc_SLL(StaticLinkList space)
{
int i = space[0].cur;
if (space[0].cur)
{
space[0].cur = space[i].cur;
}
return i;
}
Status InsertList(StaticLinkList space,int i,ElemType e)
{
int j,k,l;
if (i<1 || i>GetLinkLength(space) + 1)
return ERROR;
j = MAXSIZE - 1;
l = Malloc_SLL(space);
if (l)
{
space[l].data = e;
for (k = 0; k < i - 1; k++)
j = space[j].cur;
space[l].cur=space[j].cur;
space[j].cur = l;
return OK;
}
return ERROR;
}
int GetLinkLength(StaticLinkList L)
{
int j = 0;
int i = L[MAXSIZE - 1].cur;
while (i)
{
j++;
i = L[i].cur;
}
return j;
}
void Free_SSL(StaticLinkList space,int k)
{
space[k].cur=space[0].cur;
space[0].cur = k;
}
Status DeleteLinkList(StaticLinkList L, int i)
{
int j, k ;
if (i<1 || i>GetLinkLength(L))
return ERROR;
j = MAXSIZE - 1;
for (k = 1; k < i; k++)
j = L[j].cur;
L[j].cur = L[k].cur;
Free_SSL(L,i);
return OK;
}
循环链表
双向链表
typedef struct DulNode
{
ElemType data;
struct DulNode *prior;
struct DulNode *next;
}DulNode,*DuLinkList;