数据结构学习笔记第三节:线性表中顺序表的C与C++的实现

目录

3.1、线性表的定义

3.2、线性表的抽象数据类型

3.3、线性表的顺序存储结构

3.3.1线性表顺序存储结构C代码的实现

3.3.2线性表顺序存储结构C++代码的实现


3.1、线性表的定义

线性表(List):零个或多个数据元素的有限序列。

  1. 首先它是个序列。也就是说元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其它每个元素都有且只有一个前驱和后继。
  2. 线性表强调是有限的
  3. 在复杂的线性表中,一个数据元素可以由若干个数据项组成

3.2、线性表的抽象数据类型

线性表的抽象数据类型定义如下:

ADT 线性表 (List)
Data
    线性表的数据对象集合为(a1,a2,......,an),每个元素的类型均为DataType。
其中,除第一个元素a1外,每个元素有且只有一个直接前驱元素,除最后一个元素an外,
每一个元素有且只有一个后继元素。数据元素之间的关系是一对一的关系。
Operation
    InitList(*L);    初始化操作,建立一个空的线性表L
    ListEmpty(*L) ;    若线性表为空,返回ture,否则返回false。
    ClearList(*L) ;    将线性表清空
    GetElem(L  , i ,*e);将线性表中的第i个位置的元素返回给e
    LocateElem(L,e);    在线性表中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示            
                        成功;否则返回0表示失败
    ListInerst(*L,i,e); 在线性表L中的第i个位置插入新元素e
    ListDelete(*L,i,e);删除线性表L中第i个位置元素,并用e返回其值。
    ListLength(L); 返回线性表L的元素个数
endADT

对于不同的应用,线性表的基本操作是不同的上述操作是最基本的操作,对于实际问题中涉及的关于线性表的更复杂ode操作,完全可以用这些基本操作的组合来实现。

3.3、线性表的顺序存储结构

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。

3.3.1线性表顺序存储结构C代码的实现

1、头文件sequencelist.h

#ifndef SEQUENCELIST_H
#define SEQUENCELIST_H

#define MAXSIZE 20       /*存储空间初始分配量*/
typedef int ElemType;    /* ElemType类型根据实际情况而定,这里假设为int */
typedef struct
{
    ElemType data[MAXSIZE];  /* 数组存储数据元素,最大值为MAXSIZE */
    int length;              /*线性表当前长度*/    
}SqList;

typedef enum Bool
{
    FALSE,TRUE//枚举默认值从0开始,依次加1
}Bool;

Bool  CreatList(SqList* L);   //初始化操作,创建一个空的顺序表
Bool UnionList(SqList* L1,SqList* L2,SqList* L);  //将所有在线性表L1中但不在L2中的元素插入L2
int LocateElem(SqList L,ElemType e);//成功则返回元素的序号(从1开始),失败则返回0
int ListLength(SqList L);//顺序表的长度
Bool GetElem(SqList L, int i, ElemType e);//查找第i个位置的元素
Bool ListInsert(SqList L,int i,ElemType e);//在第i个位置插入元素
Bool ListDelete(SqList L,int i,ElemType e);//删除第i个位置的元素
Bool ListEmpty(SqList L);//判空
void clearList(SqList L);//清空顺序表
void display(SqList L);//显示当前的顺序表
#endif 

2、顺序表的源文件sequencelist.c

#include"sequencelist.h"
#include<stdio.h>
Bool InitList( SqList *L)
{
	int i;
	printf("请输入插入元素的个数(0 ~ 20):\n");
	scanf("%d",&(L->length));
	if(L->length < 0 || L->length > MAXSIZE)
		return FALSE;
	for( i = 0 ; i <= L->length; i++)
	{
		printf("请输入线性表的第%d个元素\n",i+1);
		scanf("%d",&L->data[i]);
	}
	return TRUE;   //构建成功返回TURE
	
}

//不调用已经构建的函数,直接实现顺序表的合并。
Bool UnionList(SqList* L1,SqList* L2,SqList* L)
{
	int i,j,k;
	L->length = 0;
	for( i = 0 ; i < L1->length; i++)  //先将L1中的所有元素依次插入L中
	{
		L->data[i] = L1->data[i];
	}
	for(j = 0;j < L2->length; j++)  //依次遍历L2中的各个元素
	{
		for(k = 0; k < L1->length; k++ )    
		{
			if(L2->data[j] == L1->data[k])  //依次判断L2中的元素是否是L1中的元素
				break;                      //若在则跳出当前循环,继续判断L2中的下一个元素是否是L1中的元素。
		}
		if(k == L1 ->length )       //若L2中第j个元素与L1中的每一个元素都不等,即该元素不在L1中,则可以考虑插入L表的后面
		{
			if (i >= MAXSIZE )   //判断此线性表L的长度是否超过最大长度
				return FALSE;
			L->data[i] = L2->data[j];  //没有超过则将L2中的该元素插入L中
			i++;
		}
	}
	L->length = i;
	return TRUE;

} 
 
//判断数据e在列表L中的位置
int LocateElem(SqList L,ElemType e)
{
	int i;
	for(i = 1 ; i <= L->lenght; i++ )  //如若从位置0开始则 i= 0;i < L->length
	{
		if(L->data[i-1] == e)
			return i;
	}
	return 0;
}
//在第i个位置插入元素e
Bool ListInsert(SqList L ,int i,ElemType e)
{
	int k ;   //辅助变量
	if(i<1 || L.length == MAXSIZE || i > L.length+1)//判断插入位置是否合法
		return FALSE;
	if(i <= L.length)
	{
		for(k = L.length-1; k >= i-1; k--)  //将插入位置后的面的元素依次后移避免覆盖
			L.data[k+1] = L.data[k];  
	}
	L.data[i-1] = e; //在第i个位置插入元素 (特别说明:此处的位置是从1开始)
	L.length++;     //插入元素后表的长度加一
	return TRUE;
}
//删除第i个位置的元素
Bool ListDelete(SqList L,int i,ElemType e)
{
	int k;
	if(i < 1  || L.length == 0 || i > L.length )//判断删除元素的位置是否合法
		return FALSE;
	e = L.data[i-1];  //取出要删除的元素
	if( i <= L.length) //不在表尾
	{
		//删除位置的后续元素依次前移一位
		for(k =i-1;k < L.length-1;k++)
			L.data[k] = L.data[k+1];			
	}
	L.length--;  //删除元素后整体长度减一
	return TRUE;

}

int ListLength(SqList L)
{
	return L->length;
}
//判空
Bool ListEmpty(SqList L)
{
	if(L.length == 0)
		return TRUE;
	else
		return FALSE;
}
//清空顺序表
void clearList(SqList L)
{
	L.length == 0;
}
//显示当前的顺序表
void display(SqList L)
{
	int i;
	for(i =0 ; i < L.length ; i++)
	{
		printf("%d  ",L.data[i]);
	}
	printf("\n");
}

3.3.2线性表顺序存储结构C++代码的实现

1.顺序表的头文件sequencelist.h

#ifndef SEQUENCELIST_H
#define SEQUENCELIST_H

#define MAXSIZE  20

typedef int ElemType;
class SqList
{
public:
	SqList();
	SqList(ElemType elems[],int n);	//构造函数
	bool CreatList();  // 新建一个顺序表
	bool UnionList(SqList L1 , SqList L2);
	int LocateElem(ElemType e);//按元素查找;查找成功返回元素序号(从1开始),失败则返回0 
	int ListLength(); //顺序表的长度
	bool GetElem(int i, ElemType& e); // 查找第i个位置的元素
	bool ListInsert(int i,ElemType e);  //在第i个位置插入元素
 	bool ListDelete(int i,ElemType& e); //删除第i个位置的元素
	bool ListEmpty();   //判断是否为空
	void ClearList(); // 清空顺序表
	void display();  // 显示当前的顺序表
private:
	ElemType data[MAXSIZE];  //下标从0开始,但是对线性表的操作中的下表从1开始:即第1个元素即为下标为0的元素 
	int length; 
};

#endif 

2.顺序表的源文件sequencelist.cpp

#include "sequencelist.h"
#include <iostream>
using namespace std;

SqList::SqList() // 初始化
{
	length = 0; 
} 
SqList::SqList(ElemType elems[], int n) //有参构造器 
{
	if( n > MAXSIZE)
	{
		cout<<"传入的顺序表长度超过了最大长度,只接收了前"<<MAXSIZE<<"个元素"<<endl;
		length = MAXSIZE;
	 } 
	 else
	 length = n;
	 for(int i=0; i <length;i++)
	 {
	 	data[i] = elems[i];
	 }
}

bool SqList::CreatList()
{
	cout<<"插入多少个元素(0~20)?"<<endl;
	cin>>length;
	if(length < 0 || length > MAXSIZE)
	{
		length = 0;
		return false;
	}
	for(int i = 1; i <=length; i++)
	{
		cout<<"请输入顺序线性表的第"<<i<<"个元素:";
		cin >> data[i-1]; 
	}
	return true;
}
//按元素查找 
int SqList::LocateElem(ElemType e)
{
	for(int i = 0; i < length ; i++)
	{
		if(data[i] == e)
		return i+1;
	 } 
	 return 0;
	
}
int SqList::ListLength()
{
	return length;
}
//查找第i个位置的元素 
bool SqList::GetElem(int i,ElemType& e)
{
	if(i<1 || length == 0 || i > length ) //判读查找的位置是否合法 
	return false;
	e = data[i-1];
	return true; 
}
//在第i个位置插入一个元素e
bool SqList::ListInsert(int i,ElemType e)
{
	int k;
	if(i < 1 || length == 0 || i > length+1)//判断插入位置是否合法 
	return false;
	for(k=length-1;k>=i-1;k--)
	{
		data[k+1] =data[k];  //将插入位置以后的元素依次后移 
	}
	data[i-1] = e;    //将指定位置的元素插入指定位置 
	length++;         //整体长度加一 
	return true; 
 }
 // 删除第i个位置的元素
bool SqList::ListDelete(int i,ElemType& e)
{
    if(length==0 || i<1|| i>length)//线性表满,或者i的范围不在合理范围内时返回错误
        return false;
    e=data[i-1];//取出元素
    if(i<=length)//不在表尾
    {
        //插入位置的后续元素前移一位
        for(int k=i-1;k<length-1;k++)
            data[k]=data[k+1];// 倒序挪动位置,避免覆盖问题
    }
    length--;
    return true;
}
//判断是否为空
bool SqList::ListEmpty()
{
	if(length == 0)
		return true;
	else
		return false;
}
//清空顺序表
void SqList::ClearList()
{
	length == 0;
}
 //显示函数 
void SqList::display()
{
	for(int i=0; i < length ; i++)
	cout<<data[i]<<" ";
	cout<<endl;
}
bool SqList::UnionList(SqList L1 , SqList L2)
{
	int i,j;
	for(i=0;i<L1.length;i++)
	{
		data[i] = L1.data[i];
	}
	for(j =0;j<L2.length;j++)
	if(L1.LocateElem(L2.data[j])==0) //判断L2中的元素是否在L1中
	{
		if(i >=MAXSIZE)           //判断是否超过最大长度 
			return false;
		data[i]=L2.data[j];
		i++;
	}
	length = i;
	return true;
}

3.主函数main.cpp

#include <iostream>
#include "sequencelist.h"
using namespace std;
int main(int argc, char** argv) {
	
	SqList list;
	ElemType elem,e;
	ElemType delet_num;
	bool flag;
    cout<<"            1.顺序表的创建和显示"<<endl;
    if(!list.CreatList())
        cout<<"顺序表创建失败!"<<endl;
    else
        cout<<"顺序表创建成功!    "<<endl;
    //顺序表的显示
    list.display();
    cout<<"该顺序表的总长度为:"<< list.ListLength()<<endl;
    cout<<endl<<endl;
    
	cout<<"            2.按元素查找在顺序表中的位置"<<endl;
	cout<<"请输入你要查找的元素:"<<endl;
	cin >> elem;
	cout<<"您所查找的元素的位置为:"<<list.LocateElem(elem)<<endl; 
	cout<<"            3.按位置查找"<<endl;
	list.GetElem(4,e);
    cout<<"顺序表的第4个元素是:"<<e<<endl<<endl;
	cout<<"            4.在指定位置i插入元素"<<endl;
	list.ListInsert(3,10);
	cout<<"插入元素后的顺序表为:"; 
	list.display();
	cout<<"            4.在指定位置i删除元素"<<endl;
	list.ListDelete(2,delet_num);
	cout<<"删除元素后的序列为:";
	list.display();
	cout<<"删除的元素为:"<<delet_num<<endl; 
	  cout<<"            7.合并顺序表"<<endl;
    ElemType elems1[8]={10,9,8,7,6,5,4,3};
    ElemType elems2[9]={5,6,7,8,9,10,11,1,12};

    SqList list1(elems1,8);
    SqList list2(elems2,9);
    SqList list3;
    cout<<"合并前的两个表为:"<<endl;
    list1.display();
    list2.display();
    flag=list3.UnionList(list1,list2);
    if(!flag)
        cout<<"合并后,顺序表的长度超过最大范围"<<endl;
    cout<<"该表的长度为:    "<<list3.ListLength()<<endl;
    list3.display();

 
	return 0;
}

4.主函数的执行结果

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值