线性表的定义与基本操作
定义
具有相同数据类型的n个数据元素的有限序列,n是表长,当n为0的时候线性表是一个空表。如果用L命名线性表,那么其一般表示为
L
=
(
a
1
,
a
2
,
.
.
.
,
a
i
,
a
i
+
1
,
.
.
.
,
a
n
)
L=(a_1,a_2, ...,a_i,a_{i+1},...,an)
L=(a1,a2,...,ai,ai+1,...,an)
式中,
a
1
a_1
a1是唯一的"第一个"数据元素,称为表头元素,而
a
n
a_n
an是唯一的"最后一个元素",称为表尾元素。
逻辑特性:除了第一个元素外,每个元素都有且只有一个直接前驱,除了最后一个元素外,每个元素都有且只有一个直接后继。
特点:
- 表中元素个数有限
- 表中元素具有逻辑上的顺序性,表中元素具有其先后次序。
- 表中元素都是数据元素,每个元素都是单个元素
- 表中元素的数据类型都相同,这意味着每个元素占有相同大小的存储空间
- 表中元素具有抽象性,即仅讨论元素间的逻辑关系,而不考虑元素究竟表示什么内容
**注意:线性表是一个逻辑结构,表示元素之间一对一的相邻关系。顺序表和链表指的是存储结构,两者之间没有任何关系,属于不同层面的问题。
线性表需要满足的基本操作(需要完成的接口)
- InitList(&L); 初始化表,构造一个空的线性表
- Length(L); 求表长。返回线性表L的长度,即L中元素的个数
- LocateElem(L,e); 按值查找操作。在表L中查找具有给定关键字值的元素
- GetElem(L,i); 按位查找操作,获取表L中第i个位置的元素
- ListInsert(&L, i, e); 插入操作,在表L中的第i个位置插入指定元素e
- ListDelete(&L, i, &e); 删除操作,删除表L中第i个位置的元素,并用e返回删除元素的值
- PrintList(L); 输出操作,按前后顺序输出线性表L的所有元素值
- Empty(L); 判空操作。如果L为空表,就返回true,否则返回false
- Destroy(&L); 销毁操作,销毁线性表,并释放线性表L所占用的内存空间
***注意:***①基本操作的实现取决于采用哪种存储结构(顺序表或是链表),存储结构不同,实现的算法也不一样。②"&"表示C++语言中的引用调用,在C语言中采用指针也可达到同样的效果。
顺序表(数组)实现
- DeletSmallest(&L); 从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删除元素的值。空出的位置由最后一个元素填补,如果顺序表为空,则显示出错信息并推出运行
- Turn(&L); 设计一个高效的算法,将顺序表L的说有元素逆置,要求算法的空间复杂度为O(1)
- DeleteX(&L,x); 对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素
- inXAndY(&L,x,y); 从顺序表中删除其值在给定值s与t之间(包含s和t,要求s<t)的所有元素,若s或t不合理或顺序表为空,则显示出错信息并退出运行
- Unique(&L); 从有序顺序表中删除所有其值重复的元素,使表中所有的元素的值都不一样
- Merge(&L,&R); 将两个有序数组合并为一个新的有序顺序表,并由函数返回结果顺序表
- TurnInArray(&L,m); 已知一维数组A[m+n]中依次存放两个线性表, ( a 1 , a 2 , . . . , a m ) (a_1,a_2,...,a_m) (a1,a2,...,am)和 ( b 1 , b 2 , . . . , b n ) (b_1,b_2,...,b_n) (b1,b2,...,bn)。编写一个函数,将数组中两个顺序表的位置互换,即将 ( b 1 , b 2 , . . . , b n ) (b_1,b_2,...,b_n) (b1,b2,...,bn)放在 ( a 1 , a 2 , . . . , a m ) (a_1,a_2,...,a_m) (a1,a2,...,am)前面。
- SearchInDouble(&L,x); 线性表 ( a 1 , a 2 , a 3 , . . . , a n ) (a_1,a_2,a_3,...,a_n) (a1,a2,a3,...,an)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,完成用最少时间在表中查找值为x的元素,若找到,则将其于后继元素位置相交换,若找不到,则将其插入表中并使表中元素仍递增有序
#include <iostream>
#include <cstring>
using namespace std;
typedef struct {
int * data;
int MaxSize , length;
}SqList;
void Expand(SqList &L, int ex){
int * p = L.data;
L.data = new int [L.length+ex];
for(int i = 0 ; i<L.length ; i++){
p[i] = L.data[i];
}
delete[]p;
cout<<"complete"<<endl;
}
void InitList( SqList &L , int initSize){
L.data = new int [initSize];
L.MaxSize = initSize;
L.length = 0;
}
void Length(SqList L){
cout<<L.length<<endl;
}
void LocateElem(SqList L, int e){
for(int i = 0 ; i<L.length ; i++){
if (L.data[i]==e) {
cout << i;
return;
}
}
cout<<"not found"<<endl;
}
void GetElem(SqList L, int i ){
if (i<1||i>L.length){
cout<<"超出界限"<<endl;
return;
}
cout<<L.data[i-1]<<endl;
}
void ListInsert(SqList &L, int i , int e){
if(i<1||i>L.length+1){
cout<<"超出界限"<<endl;
return;
}
if(L.length>=L.MaxSize){
Expand(L,5);
}
for(int j = L.length ; j>=i ; j--){
L.data[j] = L.data[j-1];
}
L.data[i-1] = e;
L.length++;
cout<<"complete"<<endl;
}
bool Empty (SqList L){
if (L.length==0){
return true;
}
return false;
}
void ListDelete(SqList &L , int i , int &e){
if(Empty(L)){
cout<<"顺序表为空"<<endl;
return;
}
e = L.data[i-1];
for(int j = i ; j<=L.length ; j++){
L.data[j-1] = L.data[j];
}
L.length--;
}
void PrintList(SqList L){
for (int i = 0 ; i<L.length ; i++){
cout<<L.data[i]<<" ";
}
cout<<endl;
}
void Destroy (SqList &L){
delete []L.data;
L.length=0;
L.MaxSize=0;
cout<<"complete"<<endl;
}
void DeleteSmallest(SqList &L){
if(Empty(L)){
cout<<"SqList is NULL!"<<endl;
return;
}
int a = L.data[0];
int id = 0;
int *pid = &id;
for (int i = 0; i < L.length; ++i) {
if (a>L.data[i]){
*pid = i;
a = L.data[i];
}
}
L.data[id] = L.data[L.length-1];
L.length--;
cout<<a<<"delete"<<endl;
}
void Turn (SqList &L){
if (Empty(L)){
cout<<"SqList is NULL!"<<endl;
return;
}
int i = 0 ;
int j = L.length-1;
while(i<j){
swap(L.data[i],L.data[j]);
i++;
j--;
}
}
void DeleteX(SqList &L, int x){
if (Empty(L)){
cout<<"SqList is NULL!"<<endl;
return;
}
int k = 0;
int *pk = &k;
for(int i = 0 ; i<L.length ; i++){
if (L.data[i]==x){
*pk+=1;
}
else{
L.data[i-*pk] = L.data[i];
}
}
L.length = L.length-*pk;
}
void inXAndY(SqList &L, int x , int y){
if(Empty(L)){
cout<<"SqList is Empty!"<<endl;
return;
}
if(x>y){
swap(x,y);
}
int k = 0 ;
int *pk = &k;
for(int i = 0 ; i<L.length; i++){
if (L.data[i]>=x&&L.data[i]<=y){
*pk+=1;
}
else{
L.data[i-k] = L.data[i];
}
}
L.length = L.length-*pk;
}
void Unique(SqList &L){
int *p = L.data;
L.data = new int [L.MaxSize];
bool *flag = new bool [100];
int j = 0;
memset(flag,false,10);
for(int i = 0 ; i<L.length ; i++){
if (!flag[p[i]]){
L.data[j] = p[i];
flag[p[i]]= true;
j++;
}
}
L.length = j;
delete[]p;
}
void Merge(SqList &L , SqList &R){
while (L.MaxSize<R.length){
Expand(L,R.length);
}
int *p = L.data;
int i = 0 , j = 0 , id = 0;
while(i<L.length&&j<R.length){
if (p[i]<=R.data[j]){
L.data[id] = p[i];
i++;
} else{
L.data[id] = R.data[j];
j++;
}
id++;
}
if (i<L.length){
for (; i<L.length ; i++,id++) {
L.data[id]= p[i];
}
}
if(j<R.length){
for (; j<R.length ; j++,id++) {
L.data[id] = R.data[j];
}
}
L.length = R.length+L.length;
}
void TurnInArray(SqList &L,int m ){
int *p = L.data;
L.data = new int [L.MaxSize];
int j = 0;
for (int i = m ; i <L.length ; ++i,j++) {
L.data[j] = p[i];
}
for(int i = 0 ; i<m ; i++,j++){
L.data[j] = p[i];
}
}
void SearchInDouble (SqList &L, int x){
int left = 0;
int right = L.length-1;
int m ;
while(left<right){
m = (left+right)/2;
if (L.data[m]<x){
left = m+1;
}
else if(L.data[m]>x){
right = m-1;
} else{
swap(L.data[m],L.data[m+1]);
return;
}
}
ListInsert(L,left+2,x);
}
int main() {
SqList L ;
int initSize = 10;
int show = 0;
InitList(L,initSize);
}
链表(指针)实现
//
// Created by PrimeChuJiang on 2022/11/12.
//
#include <iostream>
using namespace std;
typedef struct LNode{
int data;
struct LNode *ptr;
}LNode , *LinkList;
bool InitList(LinkList & L){
// LNode a ;
L = new LNode ;
if (L== nullptr)return false;
L->ptr = nullptr;
return true;
}
int Length(LinkList L){
LNode * p = L;
int i = 0 ;
for ( ; p->ptr != nullptr ; p = p->ptr) {
i++;
}
return i;
}
LNode* LocateElem(LinkList L, int e){
LNode *p = L;
while(p->ptr != nullptr){
if (p->data==e){
return p;
}
else{ continue;}
}
return nullptr;
}
LNode * GetElem(LinkList L , int i){
LNode *p = L->ptr;
if (i==0){return L;}
if (i<0)return nullptr;
for (int j = 1; j < i && p ; ++j) {
p = p->ptr;
}
return p;
}
void ListInsert (LinkList &L , int i , int e){
LNode *p = GetElem(L , i);
auto s = new LNode ;
s->data = p->data;
s->ptr = p->ptr;
p->ptr = s;
p->data = e;
}
bool ListDelete(LinkList &L , int i , int &e){
LNode *p = GetElem(L,i-1);
LNode *d = p->ptr;
p->ptr = d->ptr;
delete d;
return true;
}
void PrintList(LinkList L){
// LNode *p = L;
for (LNode *p= L->ptr; p!= nullptr ; p=p->ptr) {
cout << p->data;
}
}
bool Empty(LinkList L){
return L->ptr == nullptr;
}
void DestroyList(LinkList &L){
if (!L->ptr){
delete L;
return;
}
LNode *p = L->ptr;
LNode *d = L;
while(p->ptr){
delete d;
d = p;
p = p->ptr;
}
delete d;
delete p;
}
LinkList List_HeadInsert(LinkList &L, int e){
auto *p = new LNode ;
p->data = e;
p->ptr = L->ptr;
L->ptr = p;
return L;
}
LinkList List_TailInsert(LinkList &L, int e){
auto *p = new LNode ;
for(;p->ptr!= nullptr;p=p->ptr){}
auto *s = new LNode ;
s->data = e;
p->ptr = s;
s->ptr = nullptr;
return L;
}
int main(){
LinkList L ;
InitList(L);
cout <<"a"<<endl;
}