静态链表(用顺序表模拟链表)
包含两条链,一条为有效数据链表,一条为空闲节点链表
有效数据链表为带头结点的循环链表,且头结点在0号下标
空闲数据链表为带头结点的循环链表,且头结点在1号下标
注意:
添加一条空闲节点链表的目的是让插入数据时找空闲节点的时间复杂度为O(1)
该静态链表由slist.h和slist.cpp和main.cpp组成
slist.h文件
#pragma once
#define MAXSIZE 10
typedef struct SNode
{
int data;//数据
int next;//后继指针(下标)
}SNode, SLinkList[MAXSIZE];
//SLinkList s;//s长度为MAXSIZE的结构体数组
//初始化
void InitList(SNode* ps);
static bool IsFull(SNode* ps);
//头插
bool Insert_head(SNode* ps, int val);
//尾插
bool Insert_tail(SNode* ps, int val);
//判空
bool IsEmpty(SNode* ps);
//获取节点个数
int GetLength(SNode* ps);
//在ps中查找第一个key值,找到返回地址(下标),没有找到返回-1;
int Search(SNode* ps, int key);
//获取val的前驱下标
int GetPrio(SNode* ps, int key);
//删除第一个val的值
bool DelVal(SNode* ps, int val);
//输出
void Show(SNode* ps);
//清空数据
void Clear(SNode* ps);
//销毁整个内存
void Destroy(SNode* ps);
slist.cpp文件
#include"slist.h"
#include<assert.h>
#include<stdio.h>
//初始化
void InitList(SNode* ps)
{
assert(ps != NULL);
if (ps == NULL)
return;
//处理有效链表
ps[0].next = 0;
//处理空闲链表
for (int i = 1; i < MAXSIZE; i++)
{
ps[i].next = i + 1;
}
ps[MAXSIZE - 1].next = 1;
}
static bool IsFull(SNode* ps)
{
assert(ps != NULL);
if (ps == NULL)
return false;
return ps[1].next == 1;空闲链表没有数据节点
}
//头插
bool Insert_head(SNode* ps, int val)
{
assert(ps != NULL);
if (ps == NULL)
return false;
if (IsFull(ps))
return false;
//获取一个空闲节点,空闲链表的第一个数据节点
int p = ps[1].next;
//将空闲节点从空闲链删除
ps[1].next = ps[p].next;
//放入数据
ps[p].data = val;
//将空闲节点插入到有效链中
ps[p].next = ps[0].next;
ps[0].next = p;
return true;
}
//尾插
bool Insert_tail(SNode* ps, int val)
{
assert(ps != NULL);
if (ps == NULL)
return false;
if (IsFull(ps))
return false;
//找到第一个空闲节点
int p = ps[1].next;
//找到空闲节点从空闲链中删除
ps[1].next = ps[p].next;
//放入数据
ps[p].data = val;
//找尾巴
int q;
for (q = 0; ps[q].next != 0; q = ps[q].next)
{
;
}
//插入数据,将p插入到i的后面
ps[p].next = ps[q].next;//ps[p].next = 0;
ps[q].next = p;
return true;
}
//判空
bool IsEmpty(SNode* ps)
{
assert(ps != NULL);
if (ps == NULL)
return false;
return ps[0].next == 0;//有效链表中没有数据节点
}
//获取节点个数
int GetLength(SNode* ps)
{
assert(ps != NULL);
if (ps == NULL)
return -1;
int count = 0;
for (int p = ps[0].next; p != 0; p = ps[p].next)
{
count++;
}
return count;
}
//在ps中查找第一个key值,找到返回地址(下标),没有找到返回-1;
int Search(SNode* ps, int key)
{
assert(ps != NULL);
if (ps == NULL)
return -1;
//遍历有效链表
for (int p = ps[0].next; p != 0; p = ps[p].next)
{
if (ps[p].data == key)
return p;
}
return -1;
}
//获取val的前驱下标
int GetPrio(SNode* ps, int key)
{
for (int p = ps[0].next; p != 0; p = ps[p].next)
{
int q = ps[p].next;//p的后继
if (ps[q].data == key)
return p;
}
return -1;
}
//删除第一个val的值
bool DelVal(SNode* ps, int val)
{
assert(ps != NULL);
if (ps == NULL)
return false;
//获取val的前驱
int p = GetPrio(ps, val);
if (p < 0)
return false;
//将q从有效链表中删除
int q = ps[p].next;
ps[p].next = ps[q].next;
//将q添加到空闲链中
ps[q].next = ps[1].next;
ps[1].next = q;
return true;
}
//输出
void Show(SNode* ps)
{
assert(ps != NULL);
if (ps == NULL)
return ;
for (int p = ps[0].next; p != 0; p = ps[p].next)
{
printf("%d ", ps[p].data);
}
}
//清空数据//清空可以调用销毁
void Clear(SNode* ps)
{
assert(ps != NULL);
if (ps == NULL)
return ;
InitList(ps);
}
//销毁整个内存
//销毁不一定可以调用清空,销毁是销毁动态内存,在没有动态内存的情况下,才可以调用清空
void Destroy(SNode* ps)
{
assert(ps != NULL);
if (ps == NULL)
return;
Clear(ps);
}
main文件//测试函数功能
//静态链表:利用顺序表模拟链表
#include"slist.h"
#include<stdio.h>
int main()
{
SLinkList s;
printf("%d\n", sizeof(s));
InitList(s);
for (int i = 0; i < 10; i++)
{
//Insert_head(s, i);
Insert_tail(s, i);
}
Show(s);
printf("\nlen==%d\n", GetLength(s));
for (int i = -1; i < 10; i++)
printf("%d的下标为%d\n",i, Search(s, i));
printf("%d的前驱下标为%d\n", 5, GetPrio(s, 5));
DelVal(s,5);
Show(s);
return 0;
}