数据结构中,线性表分为两种:顺序表和链表。顺序表逻辑相邻,物理也相邻;链表逻辑相邻,物理不相邻。
线性表的特点:正确性、可读性、健壮性、通用性。
顺序表:在计算机内存中以数组形式保存的线性表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。将表中元素一个接一个的存入一组连续的存储单元中,这种存储结构是顺序结构。一维数组是定长顺序表。
定长顺序表
算法实现
//头文件
#ifndef _SEQLIST_H_ // 预防头文件重复引用(或直接用#pragma once)
#define _SEQLIST_H_
#define SIZE 10
typedef struct SeqList
{
int elem[SIZE];//定义数组存放数据
int length;//有效数字个数
}SeqList,*PSeqList;
void InitSeqList(PSeqList ps);//初始化顺序表
bool Insert(PSeqList ps,int pos,int val);//插入数据
bool DeletePos(PSeqList ps,int pos);//删除所在位置数据
int Search(PSeqList ps,int key);//查找给出数据的位置
bool DeleteVal(PSeqList ps,int key);//删除数据
void Clear(PSeqList ps);//清空顺序表
bool IsEmpty(PSeqList ps);//判断是否为空
int GetLength(PSeqList ps);//得到顺序表长度
void Destroy(PSeqList ps);//摧毁顺序表
void Show(PSeqList ps);//打印顺序表
#endif
定长顺序表的基本操作函数实现
#include "seqlist.h"
#include <stdio.h>
#include <assert.h>
void InitSeqList(PSeqList ps) //初始化
{
assert(ps != NULL);
if(ps == NULL)
{
return ;
}
ps->length = 0;
}
bool Insert(PSeqList ps,int pos,int val) //插入
{
assert(ps != NULL);
//assert(pos >= 0);
if(pos<0 || pos>ps->length || IsFull(ps))
{
return false;
}
for(int i=ps->length-1;i>=pos;i--)//移动原有数据
{
ps->elem[i+1] = ps->elem[i];
}
ps->elem[pos] = val; //插入新数据
ps->length++;
return true;
}
bool DeletePos(PSeqList ps,int pos) //删除
{
if(pos>ps->length || pos<0)
{
return false;
}
for(int i=pos;i<ps->length;i++)
{
ps->elem[i] = ps->elem[i+1];
}
ps->length--;
return true;
}
int Search(PSeqList ps,int key) //查找
{
for(int i=0;i<ps->length;i++)
{
if(key == ps->elem[i])
{
return i;
}
}
return -1;
}
bool DeleteVal(PSeqList ps,int key) //删除
{
if(ps->length<0)
{
return false;
}
for(int i=0;i<ps->length;i++)
{
if(ps->elem[i] == key)
{
ps->elem[i] = ps->elem[i+1];
ps->length--;
}
}
return true;
}
void Clear(PSeqList ps) //清空
{
ps->length = 0;
}
bool IsEmpty(PSeqList ps) //判空
{
return ps->length == 0;
}
int GetLength(PSeqList ps)
{
return ps->length;
}
void Destroy(PSeqList ps) //摧毁
{
Clear(ps);
}
void Show(PSeqList ps) //打印
{
for(int i=0;i<ps->length;i++)
{
printf("%d ",ps->elem[i]);
}
printf("\n");
}
不定长顺序表和定长顺序表基本一致,之比其多出了一个可以扩容的动态数组,在定义时多给出了一个记录有效数字个数的变量。如果说定长顺序表是普通一维数组,那么不定长顺序表就是动态数组,用malloc定义。
不定长顺序表
算法实现
#pragma once
#define INITSIZE 10
typedef struct DSeqList
{
int *elem;//指向保存数据数组的地址
int length;//有效数据个数
int listsize;//总格子数
}DSeqList,*PDSeqList;
void InitSeqList(PDSeqList ps);//初始化顺序表
bool Insert(PDSeqList ps,int pos,int val);//插入数据
bool DeletePos(PDSeqList ps,int pos);//删除所在位置数据
int Search(PDSeqList ps,int key);//查找给出数据的位置
bool DeleteVal(PDSeqList ps,int key););//删除数据
void Clear(PDSeqList ps);//清空顺序表
bool IsEmpty(PDSeqList ps);//判断是否为空
int GetLength(PDSeqList ps);//得到顺序表长度
void Destroy(PDSeqList ps);//摧毁顺序表
void Show(PDSeqList ps);//打印顺序表
不定长顺序表的基本操作函数实现
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "dseqlist.h"
void InitSeqList(PDSeqList ps)
{
assert(ps != NULL);
ps->elem = (int *)malloc(INITSIZE * sizeof(int));
ps->length = 0;
ps->listsize = INITSIZE;
}
static bool IsFull(PDSeqList ps)
{
return ps->length == ps->listsize;
}
static void Inc(PDSeqList ps)//扩容,总格子数扩到到原来的2倍
{
ps->elem = (int *)realloc(ps->elem,ps->listsize*2 * sizeof(int));
ps->listsize *= 2;
}
bool Insert(PDSeqList ps,int pos,int val)
{
if(pos<0 || pos>ps->length)
{
return false;
}
if(IsFull(ps))
{
Inc(ps);
}
for(int i=ps->length-1;i>=pos;i--)
{
ps->elem[i+1] = ps->elem[i];
}
ps->elem[pos] = val;
ps->length++;
return true;
}
bool DeletePos(PDSeqList ps,int pos)
{
if(pos<0 || pos>=ps->length)
{
return false;
}
for(int i=pos;i<ps->length-1;i++)
{
ps->elem[i] = ps->elem[i+1];
}
ps->length--;
return true;
}
int Search(PDSeqList ps,int key)
{
for(int i=0;i<ps->length;i++)
{
if(ps->elem[i] == key)
{
return i;
}
}
return -1;
}
bool DeleteVal(PDSeqList ps,int key)
{
int index = Search(ps,key);
if(index < 0)
{
return false;
}
return DeletePos(ps,index);
}
void Clear(PDSeqList ps)
{
ps->length = 0;
}
bool IsEmpty(PDSeqList ps)
{
return ps->length == 0;
}
int GetLength(PDSeqList ps)
{
return ps->length;
}
void Destroy(PDSeqList ps)
{
ps->length = 0;
ps->listsize = 0;
free(ps->elem);//防止内存泄漏
ps->elem = NULL;//提高健壮性,防止野指针
}
bool GetElem(PDSeqList ps,int pos,int *rtval)
{
if(pos<0 || pos>=ps->length)
{
return false;
}
*rtval = ps->elem[pos];
return true;
}
void Show(PDSeqList ps)
{
for(int i=0;i<ps->length;i++)
{
printf("%d ",ps->elem[i]);
}
printf("\n");
}
代码测试
int main()
{
DSeqList seq;
InitSeqList(&seq);
for(int i=0;i<20;i++)
{
Insert(&seq,i,i);
}
DeletePos(&seq,5);
//Search(&seq,9);
//DeleteVal(&seq,6);
//DeletePos(&seq,15);
Show(&seq);
return 0;
}