C/C++_顺序表

数据结构的生活开始啦!先来张顺序表吧!

					时刻纪念我的学习小森活!
//包含必要的头文件
#include <iostream>
using namespace std; 

//定义必须的常量和类型
#define  TRUE         1      //逻辑真
#define  FALSE        0      //逻辑假
#define  OK           1      //正确 
#define  ERROR        0      //错误  
#define  INFEASIBLE  -1      //不可能,非法操作
#define  OVERFLOW    -2      //溢出

//定义状态类型
typedef  int  Status ;


//顺序表的数据元素类型为整型(可根据需要修改为其他类型)
typedef int ElemType;

//顺序表的最大长度,做溢出错误处理,表溢出时不再扩展空间
#define  ListMaxSize  100  

//顺序表存储类型描述,SqList为顺序表类型
typedef struct {
    ElemType *elem ;   //存储空间基址
    int      length ;  //当前长度
    int      listsize; //当前分配的存储容量 
} SqList ;    

//基本操作函数原型如下
//初始化操作,为顺序表L分配空间,分配失败返回OVERFLOW
//分配成功返回OK并设置为空表
int InitListSq(SqList &L);
//取位序为i的元素,成功返回OK,失败返回ERROR
Status GetListSq(SqList L, int i, ElemType &e);
//定位元素e在顺序表中的位置,失败返回0
int LocateListSq(SqList L, ElemType e);
//插入操作
Status InsertListSq(SqList &L, int i, ElemType e);
//删除操作
Status DeleteListSq(SqList &L, int i, ElemType &e);
//遍历,默认为输出顺序表
void TraverseListSq(SqList L);
//求长度
int LengthListSq(SqList L);
//判空
Status EmptyListSq(SqList L);
//清空
void ClearListSq(SqList &L);
//销毁
void DestroyListSq(SqList &L);
//比较
int compare(int a,int b);
//删除所有e
Status DeleteESq(SqList &L,ElemType &e);


//基本操作的实现
//初始化
int InitListSq(SqList &L)
{
	L.elem=new ElemType[ListMaxSize];
	if (!L.elem ) return OVERFLOW;

    L.length = 0 ;
	L.listsize=ListMaxSize;
	return OK;
}
//取元素
Status GetListSq(SqList L, int i, ElemType &e)
{
   if (i < 1 || i > L.length) return ERROR ;
   e = *(L.elem + i - 1) ;
   return OK ;
}
//定位
int LocateListSq(SqList L, ElemType e)
{
   int i ;
   ElemType *p ;

   i = 1 ;
   p = L.elem ;
   while (i <= L.length && *p++ != e) i++ ;
   if (i <= L.length) return i ;
   else  return 0 ;
}
//插入
Status InsertListSq(SqList &L, int i, ElemType e)
{
   ElemType *p, *q ;

   if (i < 1 || i > L.length + 1) return ERROR ;
   if (L.length >= L.listsize) return OVERFLOW ;
   q = L.elem + i - 1 ;
   for(p = L.elem + L.length - 1; p >= q; p --) *(p + 1) = *p ;
   *q = e ;
   L.length ++ ;
   return OK ;
}
//删除
Status DeleteListSq(SqList &L, int i, ElemType &e)
{
   ElemType *p, *q ;

   if (i < 1 || i > L.length) return ERROR ;
   p = L.elem + i - 1 ;
   e = *p ;
   q = L.elem + L.length - 1 ;
   for (++ p; p <= q; p ++) *(p - 1) = *p ;
   L.length -- ;
   return OK ;
}
//遍历,这里是输出顺序表
void TraverseListSq(SqList L)
{
   ElemType *p ;

   p = L.elem ;
   while(p <= L.elem + L.length - 1)
      cout << *p++ << "  " ;
   cout << endl ;
}
//求长度
int LengthListSq(SqList L)
{
   return L.length ;
}
//判空
Status EmptyListSq(SqList L)
{
	return L.length==0;
}
//清空
void ClearListSq(SqList &L)
{
	L.length=0;
}
//销毁
void DestroyListSq(SqList &L)
{
	L.length=L.listsize=0;
	delete [] L.elem;
        L.elem==NULL;
}


//复杂操作的实现
//顺序表逆置,即将顺序表首尾颠倒存放
void InverseListSq(SqList &L)
{
   ElemType *p, *q, temp ;

   for (p = L.elem, q = L.elem + L.length - 1; p < q; p ++,q --){
       temp = *p ;
       *p = *q ;
       *q = temp ;
   }
}

//顺序表的逆置,对start,end之间的元素逆置
void Inverse(SqList &L, int start, int end)
{
	int i, j;
	ElemType temp;
    
	for(i=start,j=end; i<j; i++,j--)
	{
		temp = L.elem[i-1];
		L.elem[i-1] = L.elem[j-1];
		L.elem[j-1] = temp;
	}
}
//顺序表的左循环移位, m 表示向左移位个数,利用逆置算法
void CycMoveListSq(SqList &L, int m)
{
	if (m < 0) 
	{
		cout << "输入的左移位个数错误!" << endl;
		return;
	}
	if (L.length <= 1) return;

	m %= L.length;
	Inverse(L, 1, L.length);
	Inverse(L, 1, L.length-m);
	Inverse(L, L.length-m+1, L.length);
}


//顺序表排序,采用选择排序方法
void SortListSq(SqList &L)
{
  int i, j, k ;
  ElemType temp ;

  for (i = 0; i < L.length - 1; i++){
      k = i ;
      for (j = i + 1; j < L.length; j++)
	  if (*(L.elem + k) > *(L.elem+j)) k = j;
      if (k != i) {
	  temp = *(L.elem + i) ;
	  *(L.elem + i) = *(L.elem + k) ;
	  *(L.elem + k) = temp ;
      }
  }
}

//比较函数
int compare(int a,int b){
	if(a!=b)
		return 0;
	return 1;
	
}

//删除顺序表中所有元素e
Status DeleteESq(SqList &L,ElemType &e)
{
	int *n,*m,*p;
	int count=0;
	for(int i=0;i<L.length;i++){
		if (L.elem[i]==e)
			count++;
	}
	while(count--!=0){
//		i用来指示e元素所在的储存位置 
		int i=0;
//		p表示线性表第一个元素的储存位置 
		p=L.elem;
		while(i<L.length && !compare(*p++,e)) 
			i++;
//		m表示被删除元素的位置 把这个元素所在位置的地址传递给m 
		m=&(L.elem[i]);
//		n表示表为元素的位置 
		n=L.elem+L.length-1;
//		从被删除元素的位置开始,直到表尾
//		依次将被删除元素之后的元素左移 
		for(m;m<n;++m)
			*m=*(m+1);
//		表长减一 
		--L.length;              			
	}
//	删除完毕,返回1 
	return OK;
}

//约瑟夫环问题,n表示圆桌上人的个数,s表示从第几个人开始报数,m表示数到几的人离开桌子
void Josephus(SqList &L, int n,int m,int s)
{
	//初始化圆桌
	L.length=n;
	for(int i=0;i<n;i++)
		L.elem[i]=i+1;

	cout<<"圆桌初始状态:"<<endl;
	TraverseListSq(L) ;

	int len=n;
	int p=(s-1)%len;
	while(len>1)
	{
		p=(p+m-1)%len;
		int t=L.elem[p];
		for(int i=p+1;i<len;i++)
			L.elem[i-1]=L.elem[i];
		L.elem[len-1]=t;
		len--;
	}
	InverseListSq(L);
	cout<<"离开圆桌的顺序为:"<<endl;
	TraverseListSq(L) ;
}


//主函数,用来测试基本操作和复杂操作
int  main(void){
  int i, n, m, s ;
  ElemType e ;
  SqList L ;
  
  if(InitListSq(L)==OK) cout<<"顺序表初始化成功!"<<endl ;
  else {
	  cout<<"顺序表初始化失败!,程序将退出。"<<endl ;
	  return 0;
  }

  cout << "请输入要创建的顺序表长度:";
  cin >> n;
  cout << "请输入要创建的顺序表数据:\n";
  for (i=1; i<=n; i++){
      cin>>e ;
      InsertListSq(L, i, e) ;
   }
  cout << "\n创建后的顺序表为:\n";
  TraverseListSq(L) ;
  cout << "请输入要删除的元素位置:";
  cin >> i;
  if (DeleteListSq(L, i, e)) 
  {
	cout << "被删除的元素为:"<< e << endl;
	cout << "删除元素后的顺序表为:\n";
	TraverseListSq(L) ;
  }
  else
	cout << "删除的元素位置错误!\n";

  cout << "请输入要插入的元素位置:";
  cin >> i;
  cout << "请输入要插入的元素值:";
  cin>>e;
  switch(InsertListSq(L, i, e)) 
  {
  case OK: 
	  cout << "插入元素后的顺序表为:\n";
	  TraverseListSq(L) ;
	  break;
  case ERROR:
	  cout << "插入的元素位置错误!\n";
	  break;
  case OVERFLOW:
	  cout << "顺序表已满,无法插入元素!\n";
	  break;
  }

  cout << "请输入要取得的元素位序:";
  cin >> i;   
  if (GetListSq(L, i, e)) 
  {
	cout << "取得的元素为:"<< e << endl;
  }
  else
	cout << "元素位序错误!\n";
  
  cout << "请输入要查找的元素值:";
  cin >> e;

  n = LocateListSq(L, e);
  if (n != 0)
    cout << "查找成功!查找到的位置为" << n << endl ;
  else 
    cout << "查找失败!\n";
  
  cout << "排序前顺序表为:\n";
  TraverseListSq(L) ;
  SortListSq(L) ;
  cout << "排序后顺序表为:\n";
  TraverseListSq(L) ;
  
  InverseListSq(L) ;
  cout << "逆置后顺序表为:\n";
  TraverseListSq(L) ;

  cout<<"请输入向左循环移位的个数:";
  cin>>n;
  CycMoveListSq(L, n);
  cout << "向左循环移位"<<n<<"个元素后顺序表为:\n";
  TraverseListSq(L) ;

  //约瑟夫环,此问题未对n,m,s合法性检查,留给思考
  cout<<"输入圆桌人数(n):";cin>>n;
  cout<<"输入开始报数位置(s):";cin>>s;
  cout<<"输入报到几的人离开(m):";cin>>m;
  Josephus(L, n, m, s);
  
 //程序退出前,释放顺序表空间
  DestroyListSq(L);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值