c++实现数据结构顺序表的10种基本操作

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;
}

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是 C++ 实现数据结构顺序表的代码示例: ```cpp #include <iostream> using namespace std; const int MAXSIZE = 100; // 定义顺序表最大长度 template <typename T> class SeqList { private: T data[MAXSIZE]; // 存储数据元素的数组 int length; // 当前顺序表长度 public: SeqList() { length = 0; } // 构造函数,初始化为空表 ~SeqList() {} // 析构函数 bool isEmpty() { return length == 0; } // 判断是否为空表 int getLength() { return length; } // 获取当前顺序表长度 bool insert(int i, T e); // 在第 i 个位置插入元素 e bool remove(int i); // 删除第 i 个位置的元素 int search(T e); // 查找元素 e 在顺序表中的位置 T getElem(int i); // 获取第 i 个位置的元素 void printList(); // 输出顺序表中所有元素 }; template <typename T> bool SeqList<T>::insert(int i, T e) { if (i < 1 || i > length + 1) return false; // 插入位置不合法 if (length >= MAXSIZE) return false; // 顺序表已满 for (int j = length; j >= i; j--) { data[j] = data[j - 1]; // 将第 i~length-1 个元素后移一位 } data[i - 1] = e; // 将新元素插入到第 i 个位置 length++; // 长度加 1 return true; } template <typename T> bool SeqList<T>::remove(int i) { if (i < 1 || i > length) return false; // 删除位置不合法 for (int j = i; j < length; j++) { data[j - 1] = data[j]; // 将第 i+1~length 个元素前移一位 } length--; // 长度减 1 return true; } template <typename T> int SeqList<T>::search(T e) { for (int i = 0; i < length; i++) { if (data[i] == e) return i + 1; // 找到元素 e,返回其位置 } return 0; // 未找到元素 e,返回 0 } template <typename T> T SeqList<T>::getElem(int i) { if (i < 1 || i > length) throw "位置不合法"; // 获取位置不合法,抛出异常 return data[i - 1]; } template <typename T> void SeqList<T>::printList() { for (int i = 0; i < length; i++) { cout << data[i] << " "; } cout << endl; } int main() { SeqList<int> list; list.insert(1, 1); list.insert(2, 2); list.insert(3, 3); list.printList(); // 输出:1 2 3 list.remove(2); list.printList(); // 输出:1 3 cout << list.search(3) << endl; // 输出:2 cout << list.getElem(2) << endl; // 输出:3 return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_47373497

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值