写在前面
主要是根据个人的理解写的实现程序,由于时间关系没有进行测试,水平有限,所以有什么错误欢迎指出,可以评论或QQ联系
全篇使用c++实现,但是和c语言基本一样,但是可能些许语法是c++所特有的(比如引用)但是应该不影响c语言使用者阅读,语法疑惑建议Google
线性表的顺序存储实现
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<cctype>
#include<queue>
#include<iomanip>
#define LIST_INIT_SIZE 100 //线性表存储空间初始分配量
using namespace std;
const int INF=0xfffffff;
typedef long long ll;
struct SqList
{
int *elem; //存储空间基址
int length; //当前长度
int Listszie; //当前分配的存储容量
};
bool InitList(SqList &L) //线性表初始化
{
if(L.elem=(int *)malloc(LIST_INIT_SIZE*sizeof(int)))
{
L.length=0;
L.Listszie=LIST_INIT_SIZE;
return true;
}
return false;
}
bool DestroyList(SqList &L) //线性表的销毁
{
if(L.Listszie>0)
{
int *q=&L.elem[0];
for(int *i=&L.elem[L.length-1]; i>=q; i--)
free(i);
L.length=0;
L.Listszie=0;
return true;
}
return false;
}
bool ClearList(SqList &L) //线性表的清空
{
if(!L.Listszie)
return false;
for(int *i=&L.elem[L.length-1]; i>=&L.elem[0]; i--)
i=0;
return true;
}
bool EmptyList(SqList L) //判断线性表是否为空
{
return L.Listszie>0;
}
int LengthList(SqList L) //返回线性表大小
{
return L.length;
}
bool GetElem(SqList &L,int i,int &e) //返回线性表中的第i个元素
{
if(i>L.length)
return false;
e=L.elem[i];
return true;
}
bool FindElem(SqList &L,int cur_e,int &_i) //找到某个元素所在的位置
{
for(int i=0; i<L.length; i++)
if(cur_e==L.elem[i])
{
_i=i;
return true;
}
return false;
}
bool LocateElem(SqList &L,int e,int &_i) //返回第一个和e满足某个关系(现在以小于为例)的位序
{
for(int i=0; i<=L.length; i++)
{
if(e>L.elem[i])
{
_i=i;
return true;
}
}
return false;
}
bool PriorElem(SqList &L,int cur_e,int &pre_e) //寻找e的前驱,后继方法一样,这儿不再详细写了
{
int _i;
if(!FindElem(L,cur_e,_i)||_i==L.length-1)
return false;
pre_e=L.elem[L.length-2];
return true;
}
bool ListInsert(SqList &L,int i,int e) //在线性表中插入某个值
{
if(i<1||i>L.length+1)
return false;
if(L.length>=L.Listszie)
{
if(int *newbase=(int *)realloc(L.elem,(L.Listszie+LIST_INIT_SIZE)*sizeof(int)))
{
L.elem=newbase;
L.Listszie+=LIST_INIT_SIZE;
}
else
return false;
}
int *q=&L.elem[i-1];
for(int *p=&L.elem[L.length-1]; p>=q; p--)
*(p+1)=*p;
*q=e;
L.length++;
return true;
}
bool ListInsert(SqList &L,int i,int &e) //在顺序表中删除第i个数据,并返回这个值
{
if(!L.length||i<0||i>L.length)
return false;
int *q=&L.elem[i-1];
e=*q;
int *p=L.elem+L.length-1;
for(++q;q<=p;q++)
*(q-1)=*q;
L.length--;
return true;
}
链表实现
双向链表,循环链表,双向循环链表都差不多,只是多几个指针,基本操作方法是相似的,所以这里只写了单链表的部分操作,这儿只写了常用的基本操作,同样没有进行测试,可能会有一些细节错误
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
#include<iomanip>
using namespace std;
typedef long long ll;
const int INF=0xfffffff;
struct node
{
int num;
node *next;
node(int _num=0)//初始化
{
num=_num;
*next=nullptr;
}
};
node creatList()//创建链表,输入内容,假设到输入-1为结束标记
{
node *head,r,p;
head=(node*)malloc(sizeof(node));
head->next=nullptr;
int k;
cin>>k;
if(k==-1)
return *head;
while(k!=-1)
{
p=(node*)malloc(sizeof(node));
p->num=k;
p->next=nullptr;
if(!head->next)
head->next=p;
else
r->next=p;
r=p;
cin>>k;
}
r->next=nullptr;//这一句很重要
return *head;
}
node Insert(node *head,int k)//这里以有序链表为例(递增)
{
node *p=(node*)malloc(sizeof(node));
node *q=head;
while(q->next&&q->next->num<k)//这里使用双向链表可能更好理解
q=q->next;
p->num=k;
p->next=q->next;
q->next=p;
return *head;
}
void deleteList(node *head)//摧毁链表
{
node *p;
while(head->next)
{
p=head->next;
head->next=p->next;
free(p);
}
p=nullptr;
}
bool isempty(node *head)//判断链表是否为空
{
return head->next==nullptr;
}
int getlen(node *head)//返回链表长度
{
int len=0;
node *p=head;
while(p)
{
len++;
p=p->next;
}
return len;
}