线性表链式存储(静态链表)及其12种操作的实现
2015-03-26 00:45
337 查看
该表格中的所有复杂度均指的是当前程序中算法的复杂度,同一个操作算法不同复杂度不同。
对于空间复杂度:没有程序的空间复杂度为0,任何程序的运行必须要空间。当所需的空间是常数的,就是O(1);是线性的,就是O(n),以此类推。
对于空间复杂度:没有程序的空间复杂度为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"; }
相关文章推荐
- 线性表链式存储(双向循环链表)及其14种操作的实现
- 顺序存储操作的实现和线性表及其应用
- 线性表链式存储(单链表)及其15种操作的实现
- 线性表链式存储实现各种操作
- 线性表链式存储(单循环链表)及其15种操作的实现
- 线性表顺序存储(数组)及其15种操作的实现
- 【线性表一:】两种存储结构的代码实现:顺序存储和链式存储
- 栈的链式存储结构及其基本运算实现
- 二叉树基本操作实现(二叉树的链式存储)
- Java实现链式存储的线性表
- 05.线性表(四)链式存储结构.静态链表
- 集合的链式存储及操作实现
- 栈的链式存储结构及其基本运算的实现
- 采用链式存储实现,进栈、出栈操作
- 数据结构-队列的链式存储实现操作
- 第六周:栈的链式存储结构及其基本运算实现
- 栈的链式存储结构及其基本运算的实现
- 重学数据结构003——栈的基本操作及实现(链式存储)
- 链式存储结构的线性表基本实现
- 栈的链式存储结构及其基本运算实现