线性表(顺序表、单链表、循环链表等) - suzhouzc/Data-Structure GitHub Wiki
-
静态分配
#define MAX 100 ElemType elem[MAX]; //表 int n; //数据元素个数n<MAX
结构体
#define MAX 100
typedef struct
{
ElemType elem[MAX];
int length;
}Sqlist;
-
动态存储
#define LIST_INIT_SIZE 100 //存储空间的初始分配量
#define LISTINCREMENT 10 //分配增量
typedef struct
{
ElemType *elem; //存储区域的基址
int length; //当前表的长度
int listsize;//当前已分配的存储容量
}Sqlist;//顺序表的类型
-
构造一个空的顺序表L
Status InitList_Sq(SqList &L)
{
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem) exit(OVERFLOW);//存储空间分配失败
L.length=0; L.listsize=LIST_INIT_SIZE;
return OK;
} //InitList_Sq 时间复杂度为O(1)
-
销毁顺序表DestroyList_Sq(&L)释放L占用的内存空间
void DestroyList_Sq(SqList &L)
{
free(L.elem);
L.elem=NULL;
L.length=0;
L.listsize=0;
}
-
在顺序表L的第i个位置(1<=i<=L.length+1)前插入新元素e.
Status ListInsert_Sq(SqList &L,int i,ElemType e)
{
if(i<1||i>L.length+1) return ERROR;
if(L.length>=L.listsize){
newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase) exit(OVERFLOW);
L.elem=newbase;
L.listsize+=LISTINCREMENT;
}
for(int j=L.length;j>=i;j--)
L.elem[j]=L.elem[j-1]; //元素后移(从最后一个元素开始) (数组下标跟位序不同)
L.elem[i-1]=e;
++L.length;
return OK;
} //最好时间复杂度O(1)表尾,最坏时间复杂度为O(n)表头,平均是O(n/2)
-
删除数据元素ListDelete_Sq(&L,i,&e),删除顺序表中的第i(1<=i<=L.length)个元素
Status ListDelete_Sq(SqList &L,int i,ElemType &e)
{
if(i<1||i>L.length+1) return ERROR;
e=L.elem[i-1];
for( int j=i;j<L.length;j++)
L.elem[j-1]=L.elem[j];
--L.length;
return OK;
}//平均时间复杂度为 O(n-1/2)
-
按位查找:获取表L中第i个位置的元素的值。
#define InitSize 10 //顺序表的初始长度
typedef struct{
ElemType*data; //指示动态分配数组的指针
int MaxSize; //顺序表的最大容量
int length; //顺序表的当前长度
}SeqList;
ElemType GetElem(SeqList L,int i)
{
return L.data[i-1];
} //O(1);
-
按值查找:在表中查找关键字值的元素
#define InitSize 10
typedef struct{
ElemType*data;
int MaxSize;
int length;
}SeqList;
//在顺序表中查找第一个元素值等于e的元素,并返回其位序
int LocateElem(SeqList L,ElemType e)
{
for(int i=0;i<L.length;i++)
if(L.data[i]=e)
return i+1;
return 0;
} //时间复杂度为O(n+1/2)
-
定义单链表
typedef struct LNode{
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList;
//初始化一个空的单链表(不带头结点)
bool InitList(LinkList &L){
L=NULL; //空表,暂时还没有任何结点
return true;
}
//初始化一个的单链表(带头结点)
bool InitList(LinkList &L){
L=(LNode*)malloc(sizeof(LNode)); //分配一个头结点
if(L=NULL)
return false;
L->next=NULL;
return true;
}
单链表按位序插入(带头结点);插入操作。在表L中的第i个位置上插入指定元素e
status ListInsert(LinkList &L,int i,ElemType e)
{
p=L; int j=0;
while(j<i-1 && p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL || j>i-1) return ERROR;
s=(LinkList)malloc(sizeof(LNode)); //创建新结点s
if (s ==NULL)exit (OVERFLOW); //存储分配失败
s->data=e;
s->next=p->next; //将s插入到p之后
p->next=s;
return OK;
}//ListInter
不带头结点的插入操作
int ListInsert(LinkList &L,int i,ElemType e)
{
if(i==1)
{
s=(LinkList)malloc(sizeof(LNode));
if (s ==NULL)exit (OVERFLOW);
s->data=e;
s->next=L;
L=s; //修改头指针
}
else{ p=L;j=1; } //与有头结点的类似
return OK;
}
单链表的删除(带头结点)ListDelete(&L,i,&e):删除操作,删除表L中第i个位置的元素,并用e返回删除元素的值。
int ListDelete(LinkList &L,int i,ElemType &e)
{
int j=0; p=L;
while (j<i-1 && p->next)
{
j++;
p=p->next;
}
if(!(p->next)||j>i-1) return ERROR;
q=p->next; //q指向要删除的结点
e=q->data; //用e将删除元素带回到主调函数中
p->next=q->next; //从单链表中删除q结点
free(q); //释放q结点
return OK;
}
尾插法建立单链表
LinkList List_Taillnsert(LinkList &L){
int x;
L=(LinkList)malloc(sizeof(LNode));
LNode *s,*r=L;
scanf("%d",&x);
while(x!=99999){
s=(LinkList)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
*头插法建立单链表
void CreateList(LinkList &L,int n)
{//逆位序输入n个元素的值,建立带表头结构的单链表线性表L
int i;
LinkList p;
printf("请输入%d个数据:",n);
for(i=n;i>0;i++){
p=(LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next=L->next;
L->next=p;
}
}