c++实现数据结构顺序表:
初始化顺序表, 创建顺序表,增加顺序表的空间,取值,查找操作-按值查找,插入,删除,求表长,判空,合并有序(递增)顺序表,输出顺序表
顺序表优点:
随机存取,只要O(1)的时间就可以取出第i 个元素
顺序表缺点:
需要预先分配最大空间,空间过大会造成浪费,插入和删除操作需要移动大量元素
头文件代码:
#ifndef SHUNXUBIAO_H
#define SHUNXUBIAO_H
#endif
#include<iostream>
#include<stdlib.h>
using namespace std;
#define InitSize 10
int Maxsize;
//这样定义顺序表可移植性,通用性高
typedef int ElemType;//int的别名ElemType,二者等价
//ElemType=element type 用“elemtype”代表所有可能的数据类型,简单明了的概括了整体。在算法中,除特别说明外,规定ElemType的默认是int型
//typedef作用是为一种数据类型定义一个新名字,这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)
//使用typedef为现有类型创建别名,给变量定义一个易于记忆且意义明确的新名字。
typedef struct{
ElemType *elem;//顺序表首元素的地址
int length;//顺序表的长度
int Maxsize;
}SqList;
//初始化顺序表
bool InitList(SqList &L)//L前加&表示引用类型参数,函数内部的改变跳出函数后仍有效
//不加&则函数内部的改变,在跳出函数后无效
{
L.elem=new int [InitSize];
//L.elem = (ElemType*)malloc(sizeof(ElemType) * InitSize);可以代替上一行代码,二者等价
//int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100个整数的内存空间
//分配长度为num_bytes字节的内存块;如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
//当内存不再使用时,应使用free()函数将内存块释放。
L.Maxsize=InitSize;
if(!L.elem)//建表失败返回false
return false;
L.length=0;// 顺序表长度为0,表中还没有元素
return true;
}
//创建顺序表
bool CreateList(SqList &L){
int x,i=0;
cout<<"please input data"<<endl;
while( cin>>x)
{
if(x==0)
break;
else{
L.elem[i++]=x;
L.length++;
if(L.length==Maxsize){
cout<<"顺序表已满!"<<endl;
return false;
}
}}
x=-1;
return true ;
}
//增加顺序表的空间
void Increase(SqList &L,int newlen){
int*p=L.elem;//用一个指针指向原顺序表,便于后面赋值,要不然顺序表一变,就无法赋值了
L.elem = (ElemType*)malloc(sizeof(ElemType) * (L.Maxsize + newlen));
//重新给L分配L.Maxsize + newlen的空间
L.Maxsize=L.Maxsize+newlen;
//复制原来的元素
for(int i=0;i<L.Maxsize;i++){
L.elem[i]=p[i];
}
free(p);//释放原来的空间
}
//取值
ElemType GetElem(SqList &L, int i)
//使用ElemType 可以是各种类型的函数,不指定具体函数类型,可改性高
{
if (i<1 || i>L.length)
//判断i 值是否合理
return -1;
return L.elem[i - 1];
}
//查找操作-按值查找:查找表L中第一个元素值为e的元素,并返回其位序
int LocateElem(SqList &L, ElemType e) {
for (int i = 0; i < L.length; i++)
if (L.elem[i] == e)
return i + 1; //数组下标为i的元素值等于e,返回其位序i+1
return 0; //返回值为0,说明查找失败
}
//查找算法复杂度:
/*最好情况:查找一次就找到(即找的是表中第一个元素)时间复杂度为O(1)
最坏情况:查找n=L.length次,时间复杂度为O(n)
平均情况:若元素在第一个位置需要比较1次,在第二个位置需要比较2次,在第i 个位置需要比较i 次,则平均时间复杂度=pi*i(从1到n求和)pi是查找概率
若查找概率均等则平均时间复杂度为O(n)
*/
//插入操作:在表L的位序i上插入指定元素e
bool InsertList(SqList &L, int i, ElemType e) {
if (i<1 || i>L.length + 1) //判断要插入的位序i是否合法(合法范围[1,length+1],即首部和尾部之间)
return false;
if (L.length >= L.Maxsize) //判断当前存储空间是否已满,若已满,不能插入
return false;
for (int j = L.length; j >= i; j--) //将第i个元素及之后的元素后移
L.elem[j] = L.elem[j - 1];//从最后一个元素开始后移,直到第i个元素后移
L.elem[i - 1] = e; //位序为i处放入指定元素e
L.length++; //顺序表长度+1
return true;
}
/*插入算法复杂度
在第i 个位置插入,则从第i个元素到第n个元素都要后移,则需要移动n-i+1 ;有n+1种插入情况:从第一个插入到插入到第n+1位置
平均时间复杂度=pi*(n-i+1)(从1到n+1求和)pi是每个位置插入的概率 ,若插入概率均等则平均时间复杂度为 O(n) */
//删除操作:删除表中位序为i的元素,并用e返回删除元素的值
bool ListDelete(SqList &L, int i, ElemType& e) {
if (i<1 || i>L.length) { //判断要删除的位序是否合法(合法范围为[1,length])
return false;
}
e = L.elem[i - 1]; //位序i的元素保留在e中,防止被覆盖,以后可能有用
for (int j = i; j < L.length; j++) //将第i个元素之后的元素前移,从第i+1个元素开始前移
L.elem[j - 1] = L.elem[j];
L.length--; //顺序表长度-1
return true;
}
/*删除算法复杂度
顺序表删除一共有n种情况,每个情况移动元素个数为n-(i+1)+1=n-i(删除第i 个元素,从第i+1个元素开始移动)
平均时间复杂度=pi*(n-i)(从1到n求和)pi是删除概率;若删除概率均等则平均时间复杂度=O(n)
*/
//求表长
int Length(SqList &L) {
return L.length;
}
//判空
bool Empty(SqList &L) {
if (L.length == 0) {
printf("顺序表为空!\n");
return true;
}
else {
printf("顺序表非空!\n");
return false;
}
}
//合并有序(递增)顺序表
//不断从La,Lb中取数,比较大小,将较小者放入Lc中,一直进行下去,直到把其中一个顺序表La或Lb中的数取完为止,若La或Lb中仍有多余,则把多余的数放入Lc表尾
void MergeSqlist(SqList &La,SqList &Lb,SqList &Lc)
{
int i,j,k;
i=j=k=0;
Lc.length=La.length+Lb.length;// 新表的长度是待合并两表的长度之和
Lc.elem=new int[Lc.length];//为合并后的新表分配一段空间
while(i<La.length&&j<Lb.length)
{
if(La.elem[i]<=Lb.elem[j])//按递增顺序排列
{
Lc.elem[k]=La.elem[i];
i++;
k++;
}
else{
Lc.elem[k]=Lb.elem[j];
j++;
k++;
}
}
while(i<La.length&&j>=Lb.length)// La有剩余,将La中剩余元素放入Lc表尾部
{
Lc.elem[k]=La.elem[i];
k++;
i++;
}
while(j<Lb.length&&i>=La.length)//Lb有剩余,将Lb中剩余元素放入Lc表尾部
{
Lc.elem[k]=Lb.elem[j];
k++;
j++;
}
}
//输出顺序表
void showSqList(SqList &L){
for(int i=0;i<L.length;i++)
cout<<L.elem[i]<<",";
}
主方法代码:
#include<iostream>
#include"Shunxubiao.h"
using namespace std;
int main()
{ //struct Sqlist;
SqList L1;
SqList L2;
SqList L3;
InitList(L1);
InitList(L2);
CreateList(L1);
CreateList(L2);
//cout<<L.elem [0]<<endl;
MergeSqlist(L1,L2,L3);//合并有序链表L1,L2
showSqList(L3);// 输出合并后的有序链表L3
return 0;
}