线性表具有两种存储结构,分别为:顺序存储结构和链式存储结构。
顺序存储结构就是顺序表。
链式存储结构就是链表。
一、顺序表
顺序表具有两种特性:随机访问特性与占用连续的存储空间。随机访问特性可以使得顺序表可以直接访问任意一个表中元素。而占用连续的存储空间要求顺序表必须预先分配好一个连续的存储空间,一旦分配好,在操作过程中会始终保持不变。
代码部分(代码用c语言实现,只适用于理论,若需要进行实际应用,需要自行修改)
线性表的结构体定义
#define MaxSize 100
typedef struct Sqlist
{
int data[MaxSize]; // 定义顺序表存放元素的数组
int length; //顺序表长度
}Sqlist;
结构体的定义书写起来会比较麻烦,用下面方式书写,可以大大提高效率
int arr[ maxSize];
int n;
顺序表的操作
操作有四大类:增删改查
按照元素查找算法
int Find_Elem(Sqlist l,int x){
int i;
for ( i = 0; i < l.length; ++i)
{
if (l.data[i] == e)
{
return i;
}
}
return i;
}
插入数据元素算法
/*线性表中的插入算法 在p位置上插入e,如果p不正确,则返回0;p正确 插入 返回1*/
int insertElem(Sqlist *l,int p,int x){
int i;
if (p < 0 || p < l->length || l->length == maxSize )
{
return 0;
}else{
for (i = l->length - 1; i >= p ; --i)
{
l->data[i+1] = l->data[i];
}
l->data[p] = x;
l->length = l->length + 1;
return 1;
}
}
删除数据元素的算法
/*删除顺序表中下标为p的元素,成功返回1,否则返回0,将删除的元素赋值给e*/
void Delet_Elem(Sqlist *l,int p,int x){
int i;
if (p < 0 || p > l->length)
{
return 0;
}else{
x = l->data[p];
for(i = p; i <= l->length; ++i){
l->data[i] = l->data[i+1];
}
l->length = l->length - 1;
return 1;
}
}
二、链表
相对于顺序表,链表不支持随机访问,并且存储时无需使用一个连续的区域进行存储,并且指针会占用链表结点的一些空间,所以链表对于存储空间的利用率比顺序表稍低一些。正是因为使用了指针和结点,所以链表具有动态分配内存空间的功能。线性表的链表存储结构有很多种形式:单链表、双链表、循环链表。这里只使用单链表和双链表。
代码部分(代码用c语言实现,只适用于理论,若需要进行实际应用,需要自行修改)
单链表以及双链表的定义
// LNode
typedef struct LNode
{
/* data */
int data;
struct LNode *next;
}LNode;
// DLNode
typedef struct DLNode{
/* data */
int data;
struct DLNode *perior;
struct DLNode *next;
}DLNode;
单链表以及双链表的初始化
单链表和双链表的初始化会使用C语言中的malloc函数和sizeof函数
LNode *L = (LNode*)malloc(sizeof(LNode));
DLNode *L = (DLNode *)malloc(sizeof(DLNode));
单链表的操作
尾插法建立单链表
void CreateListR(LNode *C,int a[],int n){
LNode *s,* r; // s用来指向新申请的结点,r始终指向c的终端结点
int i;
C = (LNode *)malloc(sizeof(LNode));//申请C的头结点
C->next = NULL;
r = C;
for ( i = 0; i < n; ++i)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = a[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
头插法建立单链表
void CreateListF(LNode *C,int a[],int n){
LNode *s;
int i;
C = (LNode *)malloc(sizeof(LNode));
C->next = NULL;
for ( i = 0; i < n; ++i)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = a[i];
/*头插法关键*/
s->next = C->next;
C->next = s;
}
}
查找链表C(带头结点)是否存在x结点,若存在,删除该结点返回1,否则返回 1 查找和删除
int findAndDelete(LNode *l,int x){
LNode *p, *q;
p = l;
//查找
while (p->next != NULL)
{
/* code */
if (p->next->data == x)
{
break;
}
p = p->next;
}
if (p->next == NULL)
{
return 0;
}else{
/*删除*/
q = p->next;
p->next = p->next->next;
free(q);
return 1;
}
}
双链表的操作
采用尾插法建立双链表
void CreateDlistR(DLNode *l, int a[], int n){
DLNode *r,*s;
int i;
l = (DLNode *)malloc(sizeof(DLNode));
l->perior = NULL;
l->next = NULL;
r = l;
for ( i = 0; i < n; ++i)
{
/* code */
s = (DLNode *)malloc(sizeof(DLNode));
s->data = a[i];
/*插入尾部*/
r->next = s;
s->perior = r;
r = s;
}
r->next = NULL;
}
双链表查找
DLNode* findElem3(DLNode *C, int x){
DLNode *p = C->next;
while (p != NULL)
{
/* code */
if (p->data == x)
{
/* code */
break;
}
p = p->next;
}
return p;
}