线性表(Linear List):
- 概念:由同类数据元素构成的有序序列的线性结构。
- 表中元素个数称为线性表的长度
- 线性表没有元素时,称为空表
- 表起始位置称为表头,表结束位置称为表尾
数组:线性表的顺序存储实现
Data | a1 | a2 | a3 | … | a(i) | a(i+1) | … |
---|
//MAXSIZE表示数组的长度
//Last表示数组最后一个元素的下标
typedef struct{
ElementType Data[MAXSIZE];
int Last;
}List;
List L,*PtrL;
//访问数组下标为i的元素:L.Data[i]或者PtrL->Data[i]
//数组长度:L.Last+1或者PtrL->Last+1
- 主要操作的实现:
- 1.初始化:
List *MakeEmpty(){ List *PtrL; #初始化一个List指针 //函数原型:void *malloc(unsigned int size) //在内存的动态存储区中分配一个长度为size的连续空间 //详细:https://baike.baidu.com/item/malloc%E5%87%BD%E6%95%B0/8582146?fromtitle=malloc&fromid=659960&fr=aladdin PtrL = (List *)malloc(sizeof(List)); #分配一个List大小的空间给PtrL Ptrl->Last = -1; return PtrL; }
- 2.查找(时间性能为O(n):
int Find(ElementType X, List *PtrL){ int i = 0; while(i <= PtrL->Last && PtrL->Data[i] != X) i++; if(i > PtrL->Last) return -1; //如果未找到返回-1 else return i; //找到返回下标i }
- 3.插入操作:
void Insert(ElementType X, int i, List *PtrL){ int j; if(i > MAXSIZE){ //已经达到最大存储值,不能插入 cout<<"表满"; return; } if(i < 1 || i > PtrL->Last + 2){ cout<<"位置不合法"; //不合法插入位置 return; } for(j = PtrL->Last; j >= i-1; j--){ PtrL.Data[j+1] = PtrL.Data[j]; //将i-1后面的元素后移一个位置 } PtrL.Data[i-1] = X; //插入元素X PtrL.Last++; //最大长度增加1 }
- 删除操作:
void Delete(int i, List *PtrL){ int j; if(i < 1 || i > PtrL->Last + 1){ cout<<"不存在第"<<i<<"个元素"; //不合法删除位置 return; } for(j = i-1; j < PtrL->Last; j++){ PtrL->Data[j] = PtrL->Data[j+1]; //将i-1后面的元素前移一个位置 } PtrL->Last--; //最大长度减一 }
完整代码:c++版 点击查看
链表:线性表的链式存储实现
定义结点
typedef struct Node{
ElementType Data; //定义数据域
struct Node *Next; //#定义Node类型的Next指针域
}List;
List L,*PtrL;
-
主要操作实现:
- 1.求表长:
int Length(List *PtrL){ List *p = PtrL; //将p指向表的第一个结点 int j = 0; while(p){ //当指针不为空时,遍历表 p = p->Next; j++; } return j; //返回链表长度 }
- 2.查找:
- (1)按序号查找:
List *FindKEle(int K, List *PtrL){ List *p = PtrL; //p指向表的第一个结点 int i = 1; while(i < K && p != NULL){ p = p->Next; i++; } if(i==K){ return p; //找到第K个元素,返回指针 } else return NULL; //未找到返回空 }
- (2)按值查找:
int FindEle(int X, List *PtrL){ int i = 0; List *p = PtrL; //指向表第一个结点 while(p != NULL && p->Data != X){ ++i; p = p->Next; } if(p != NULL){ return i+1; //找到则返回结点 } }
- 插入操作:
示例图:
示例代码(尾插法):List *Insert(int i, int X, List *PtrL){ List *p, *s; if(i == 1){ //如果在第一个结点插入,单独考虑 s = (List *)malloc(sizeof(List)); //分配List大小的空间 s->Data = X; s->Next = PtrL; PtrL = s; //PtrL指向新的头结点s return PtrL; //返回头结点 } p = FindKEle(i-1, PtrL); //找到第i-1个元素的结点并返回 if(p == NULL){ //不存在第i个结点 cout<<"插入位置不合法"; } else{ //否则将结点插在i-1的后面 s = (List *)malloc(sizeof(List)); s->Data = X; s->Next = p->Next; p->Next = s; } return PtrL; //返回头结点 }
- 删除操作:
示例图:
示例代码:void Delete(int i, List *PtrL){ List *p, *s; if(i == 1){ //如果要删除的结点在第一个 s = PtrL; PtrL = PtrL->Next; free(s); //释放内存资源 } p = FindKEle(i-1, PtrL); if(p == NULL){ cout<<"无第"<<i<<"个元素"; //无该元素 } else if(p->Next == NULL){ cout<<"无第"<<i<<"个元素"; } else{ s = p->Next; //删除节点 p->Next = s->Next; free(s); //释放内存资源 } }