该表格中的所有复杂度均指的是当前程序中算法的复杂度,同一个操作算法不同复杂度不同。
对于空间复杂度:没有程序的空间复杂度为0,任何程序的运行必须要空间。当所需的空间是常数的,就是O(1);是线性的,就是O(n),以此类推。
操作 | 时间复杂度(T(n)) | 空间复杂度(S(n)) |
判断是否为空 | O(1) | O(1) |
得到长度 | O(n) | O(1) |
转置线性表 | O(n) | O(1) |
得到指定下标的元素 | O(n) | O(1) |
得到指定元素的下标 | O(n) | O(1) |
插入元素 | O(n) | O(1) |
删除元素 | O(n) | O(1) |
冒泡排序 | O(n^2) | O(1) |
清空当前线性表 | O(n) | O(1) 因为整个一维数组的空间早已经声明,只是使用和不使用之分,无开辟新内存和回收内存 |
归并两个已经有序的线性表(长度分别n,m)的交集到第一个线性表,且保持新表有序 | O(n+m) 最坏的情况下 | O(1) 事实上是多使用了O(m)的内存,因为要将s2的所有元素复制到s1中 |
/* 数据结构分析与学习专栏
* Copyright (c) 2015, 山东大学计算机科学与技术专业学生
* All rights reserved.
* 作 者: 高祥
* 完成日期: 2015 年 3 月 25 日
* 版 本 号:003
*任务描述:针对线性表的采用顺序存储结构,实现15个基本操作
* 1:建立静态链表,填充元素
* 2:输出静态链表
* 3:判断静态链表是否为空
* 4:求静态链表的长度
* 5:反转静态链表
* 6:查找静态链表指定下标的元素
* 7:求出给定元素在静态链表中第一次出现的位置
* 8:向静态链表中的指定位置插入元素
* 9:删除静态链表中指定位置的元素
* 10:清空当前静态链表
* 11:将静态链表按照升序排序
* 12:将两个静态链表归并到第一个静态链表中并按照升序排列
*主要函数:
* 1.void InitList(SLinkList &s);
//初始化静态链表:将一维数组的各分量链成一个备用链表,s[0].cur为第一个结点
//0表示空指针
* 2.int Malloc(SLinkList &s);//若备用链表空间非空,则返回分配的结点下标,否则返回0
* 3.void Free(SLinkList &s,int index);//将下标为k的空闲节点回收到备用链表中
* 4.void FillList(SLinkList &s,int &head);
//填充静态链表的元素,注意:head要使用引用传值
* 5.void Output(SLinkList s,int head);//输出静态链表
* 6.Status IsEmpty(SLinkList s,int head);//判断静态链表是否为空
* 7.int ListLength(SLinkList s,int head);//求静态链表的长度
* 8.void ReverseList(SLinkList &s,int head);//反转静态链表
* 9.void GetElem(SLinkList s,int index,int head);//得到指定下标的元素
* 10.void GetIndex(SLinkList s,ElemType elem,int head);//得到指定元素的下标
* 11.void InsertList(SLinkList &s,int head,int index,ElemType elem);//插入元素
* 12.void DeleteList(SLinkList &s,int head,int index);//删除结点
* 13.Status ClearList(SLinkList &s,int head);//清空静态链表
* 14.void BubbleSort(SLinkList &s,int head);//冒泡排序
* 15.void MergeList(SLinkList &s1,int head1,SLinkList &s2,inthead2);
//归并两个静态链表到第一个静态链表中并保持升序
*/
#include<iostream>
#include<algorithm>
using namespace std;
#define OK 1
#define FALSE 0
#define ERROR 0
#define MAXSIZE 100000
typedef int ElemType;
typedef int Status;
typedef struct
{
ElemType data;
int cur;
} component,SLinkList[MAXSIZE];
void Interaction();
void InitList(SLinkList &s);
//初始化静态链表:将一维数组的各分量链成一个备用链表,s[0].cur为第一个结点,0表示空指针
int Malloc(SLinkList &s);//若备用链表空间非空,则返回分配的结点下标,否则返回0
void Free(SLinkList &s,int index);//将下标为k的空闲节点回收到备用链表中
void FillList(SLinkList &s,int&head);//填充静态链表的元素,注意:head要使用引用传值
void Output(SLinkList s,int head);//输出静态链表
Status IsEmpty(SLinkList s,int head);//判断静态链表是否为空
int ListLength(SLinkList s,int head);//求静态链表的长度
void ReverseList(SLinkList &s,inthead);//反转静态链表
void GetElem(SLinkList s,int index,inthead);//得到指定下标的元素
void GetIndex(SLinkList s,ElemType elem,inthead);//得到指定元素的下标
void InsertList(SLinkList &s,inthead,int index,ElemType elem);//插入元素
void DeleteList(SLinkList &s,inthead,int index);//删除结点
Status ClearList(SLinkList &s,inthead);//清空静态链表
void BubbleSort(SLinkList &s,inthead);//冒泡排序
void MergeList(SLinkList &s1,inthead1,SLinkList &s2,int head2);
//归并两个静态链表到第一个静态链表中并保持升序
int main()
{
SLinkList s1,s2;
Interaction();
int operate;
int head1,head2;
while(cin>>operate)
{
switch(operate)
{
case 0:
return 0;
case 1:
InitList(s1);
FillList(s1,head1);
break;
case 2:
Output(s1,head1);
break;
case 3:
if(IsEmpty(s1,head1))
{
cout<<"静态链表为空。\n";
}
else
{
cout<<"静态链表不为空。\n";
}
break;
case 4:
cout<<"静态链表的长度是:"<<ListLength(s1,head1)<<endl;
break;
case 5:
ReverseList(s1,head1);
break;
case 6:
cout<<"请输入下标:";
int index;
cin>>index;
GetElem(s1,index,head1);
break;
case 7:
cout<<"请输入元素大小:";
ElemType elem;
cin>>elem;
GetIndex(s1,elem,head1);
break;
case 8:
cout<<"请输入要插入的元素大小及其位置:";
cin>>elem>>index;
InsertList(s1,head1,index,elem);
break;
case 9:
cout<<"请输入要删除的元素的下标:";
cin>>index;
DeleteList(s1,head1,index);
break;
case 10:
if(ClearList(s1,head1))
{
cout<<"清空静态链表成功。\n";
}
break;
case 11:
BubbleSort(s1,head1);
break;
case 12:
InitList(s2);
FillList(s2,head2);
MergeList(s1,head1,s2,head2);
break;
default:
cout<<"请输入正确的操作数字!\n";
break;
}
}
return 0;
}
void Interaction()
{
cout<<"请输入对应操作的序号:\n";
cout<<"0:退出程序;\n";
cout<<"1:建立静态链表,填充元素;\n";
cout<<"2:输出静态链表;\n";
cout<<"3:判断静态链表是否为空;\n";
cout<<"4:求静态链表的长度 ;\n";
cout<<"5:反转静态链表;\n";
cout<<"6:查找静态链表指定下标的元素;\n";
cout<<"7:求出给定元素在静态链表中第一次出现的位置;\n";
cout<<"8:向静态链表中的指定位置插入元素;\n";
cout<<"9:删除静态链表中指定位置的元素;\n";
cout<<"10:清空当前静态链表;\n";
cout<<"11:将静态链表按照升序排序;\n";
cout<<"12:将两个静态链表归并到第一个静态链表中并按照升序排列;\n";
}
void InitList(SLinkList &s)
//初始化静态链表:将一维数组的各分量链成一个备用链表,s[0].cur为第一个结点,0表示空指针
{
for(int i=0; i<MAXSIZE-1; i++)
{
s[i].cur=i+1;
}
s[MAXSIZE-1].cur=0;
}
int Malloc(SLinkList &s)//若备用链表空间非空,则返回分配的结点下标,否则返回0
{
int i=s[0].cur;
if(i)
{
s[0].cur=s[i].cur;//取出一个备用结点,更新下一个可用结点的下标
}
return i;
}
void Free(SLinkList &s,int index)//将下标为k的空闲节点回收到备用链表中
{
s[index].cur=s[0].cur;
s[0].cur=index;
}
void FillList(SLinkList &s,int&head)//填充静态链表的元素,注意:head要使用引用传值
{
cout<<"请输入元素的个数:";
int listsize;
cin>>listsize;
head=Malloc(s);//生成头结点
int r=head;//r是尾结点
cout<<"请输入元素:";
for(int i=1; i<=listsize; i++)
{
int index=Malloc(s);
if(index)
{
cin>>s[index].data;
s[r].cur=index;
r=index;//更新尾结点的索引
}
}
s[r].cur=0;//最后指向空指针
cout<<"静态链表是:";
Output(s,head);
}
void Output(SLinkList s,int head)//输出静态链表
{
if(!IsEmpty(s,head))
{
int index=s[head].cur;//第一个结点
while(index)
{
cout<<s[index].data<<" ";
index=s[index].cur;//更新结点
}
cout<<endl;
}
else
{
cout<<"静态链表为空,无法输出。\n";
}
}
Status IsEmpty(SLinkList s,int head)//判断静态链表是否为空
{
if(s[head].cur==0)
{
return OK;
}
return FALSE;
}
int ListLength(SLinkList s,int head)//求静态链表的长度
{
int length=0;
int index=s[head].cur;
while(index)
{
length++;
index=s[index].cur;
}
return length;
}
void ReverseList(SLinkList &s,inthead)//反转静态链表
{
int p,q;
p=s[head].cur;
q=s[p].cur;
s[p].cur=0;
while(q)
{
int index=s[q].cur;//预存下一个结点
s[q].cur=p;
p=q;//更新结点
q=index;
}
s[head].cur=p;//最后转换头结点
cout<<"反转后的静态链表是:";
Output(s,head);
}
void GetElem(SLinkList s,int index,inthead)//得到指定下标的元素
{
if(index<1||index>ListLength(s,head))
{
cout<<"位置越界,无法输出。\n";
return;
}
int num=1;
int index2=s[head].cur;
while(1)
{
if(num==index)
{
cout<<"第"<<index<<"个元素是:"<<s[index2].data<<endl;
return;
}
num++;
index2=s[index2].cur;
}
}
void GetIndex(SLinkList s,ElemType elem,inthead)//得到指定元素的下标
{
int num=1;
int index=s[head].cur;
while(index)
{
if(s[index].data==elem)
{
cout<<"元素"<<elem<<"是静态链表中的第"<<num<<"个元素。\n";
return;
}
num++;
index=s[index].cur;
}
cout<<"未找到,已退出。\n";
}
void InsertList(SLinkList &s,inthead,int index,ElemType elem)//插入元素
{
if(index<1||index>ListLength(s,head))
{
cout<<"位置越界,无法插入。\n";
return;
}
int num=0;
int p=head;
while(num<=index-2)
{
num++;
p=s[p].cur;
}
int newnode=Malloc(s);
s[newnode].data=elem;
s[newnode].cur=s[p].cur;
s[p].cur=newnode;
cout<<"静态链表是:";
Output(s,head);
}
void DeleteList(SLinkList &s,inthead,int index)//删除结点
{
if(index<1||index>ListLength(s,head))
{
cout<<"位置越界,无法删除。\n";
return;
}
int num=0;
int p=head;
while(num<=index-2)
{
num++;
p=s[p].cur;
}
int deletenode=s[p].cur;
s[p].cur=s[deletenode].cur;
Free(s,deletenode);//回收被删除的结点
cout<<"静态链表是:";
Output(s,head);
}
Status ClearList(SLinkList &s,inthead)//清空静态链表
{
int index=s[head].cur;
while(index)
{
int index2=s[index].cur;
Free(s,index);//回收结点
index=index2;
}
return OK;
}
void BubbleSort(SLinkList &s,inthead)//冒泡排序
{
int i=s[head].cur,j;
while(i)
{
j=s[i].cur;
while(j)
{
if(s[i].data>s[j].data)
{
swap(s[i].data,s[j].data);
}
j=s[j].cur;
}
i=s[i].cur;
}
cout<<"排序后的静态链表是:";
Output(s,head);
}
void MergeList(SLinkList &s1,inthead1,SLinkList &s2,int head2)
//归并两个静态链表到第一个静态链表中并保持升序
{
if(!IsEmpty(s1,head1)&&!IsEmpty(s2,head2))
{
BubbleSort(s1,head1);//先对两个分静态链表排序
BubbleSort(s2,head2);
int p=s1[head1].cur,q=s2[head2].cur;
int index=head1;
while(p&&q)//当没有链表归并完时
{
if(s1[p].data<=s2[q].data)
{
s1[index].cur=p;
//因为归并到第一个链表中,所以s1[p].data<=s2[q].data时,只需要改变链表s1的结点指向即可,无需声明新结点
index=p;//更新“新”静态链表的结点指针
p=s1[p].cur;//更新未归并的结点的指针
}
else
{
int newnode=Malloc(s1);//声明新节点,复制到静态链表s1中
s1[newnode].data=s2[q].data;
s1[index].cur=newnode;//完成指针转移
index=newnode;
q=s2[q].cur;
}
}
while(q)//当s1本身完成归并但是s2未完成归并时,将剩余的所有s2的结点全部复制到s1链表中
{
int newnode=Malloc(s1);
s1[newnode].data=s2[q].data;
s1[index].cur=newnode;
index=newnode;
q=s2[q].cur;
}
s1[index].cur=0;//终结新链表
if(p)//当s2完成归并但是s1未完成归并时,只需要将“新”s1最后一个元素的指针连接到将要被归并的第一个元素上
{
s1[index].cur=p;
}
cout<<"归并后的静态链表是:";
Output(s1,head1);
ClearList(s2,head2);
return;
}
cout<<"静态链表为空,无法归并。\n";
}