【数据结构】顺序表王道综合题

首先是大概的一个框架,然后重点说的是第12题。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
typedef struct LNode{
	int data[100];
	int length;
}SqList;

int n,m;
void InitList(SqList &L){						//构造顺序表 
	int i;
	cin >> n;
	for(i=0;i<n;i++)
		cin >> L.data[i];
	L.length=n;
}
void Trave(SqList &L){							//遍历顺序表 
	int i;
	for(i=0;i<L.length;i++)
		cout << L.data[i] << " ";
	cout << endl;
	cout << "The Length is "<< L.length <<endl;
} 
void Reverse(SqList &L,int left,int right){		//逆置函数 ,从left处到right处的逆置
	int i,num;
	for(i=left;i<=(right-left)/2;i++){
		num=L.data[right-i];
		L.data[right-i]=L.data[i];
		L.data[i]=num;
	}
	return ;
}

int main()
{
	SqList L;
	SqList La,Lb;
	while(true){
		InitList(L);
		//Trave(L);
		//InitList(La);
		//Trave(La);
		//f6(L);
		//f7(L,La);
		//Lb=f7(L,La);
		//Trave(Lb);
		//f8(L);
		//Trave(L);
		//f9(L,9);
		//f12(L); 
		//cout << f12(L) << endl;
		Trave(L);	
	}
	return 0;
}

下面是一些题目的函数:

void f6(SqList &L){						//删除有序表中的重复元素 
	int i,k=0;
	for(i=1;i<L.length;i++){
		if(L.data[k]!=L.data[i]){
			k++;
			L.data[k]=L.data[i];
		}
	}
	L.length=k+1;
}
SqList f7(SqList &La,SqList &Lb){		//合并两个有序表 
	SqList L;
	int i,j,k=0;
	for(i=0,j=0;i<La.length,j<Lb.length;){
		if(La.data[i]>=Lb.data[j]){
			L.data[k++]=Lb.data[j];
			j++;
		}
		else if(La.data[i]<Lb.data[j]){
			L.data[k++]=La.data[i];
			i++;
		}
	}
	if(i<La.length){
		for(;i<La.length;i++){
			L.data[k++]=La.data[i];
		}
	}
	else if(j<Lb.length){
		for(;j<Lb.length;j++){
			L.data[k++]=Lb.data[j];
		}
	}
	L.length=k;
	return L;
}
void f8(SqList &L){			//顺序表L=(La,Lb)处理后L=(Lb,La) 
	int n,m;
	cin >> n >> m;
	Reverse(L,0,n+m-1);
	//Trave(L);
	Reverse(L,0,n-1);
	Reverse(L,n,n+m-1);
} 
void f9(SqList &L,int x){			//O(n) 查找元素x然后与后面节点交换数值
	int i,j,k=0;					//找不到的时候插入到有序表中
	for(i=0;i<L.length;i++){
		if(L.data[i]==x&&i!=L.length-1){
			L.data[i]=L.data[i+1];
			L.data[i+1]=x;
			return ;
		}
		if(L.data[i]>x){
			for(j=L.length;j>i;j--)
				L.data[j]=L.data[j-1];
			L.data[j]=x;
			L.length++;
			return ;
		}
	}
} 
int f11(SqList &La,SqList &Lb,int n){	//找到两个升序列合并之后的中位数 
	int s1=0,d1=n-1,m1;
	int s2=0,d2=n-1,m2;
	while(s1!=d1||s2!=d2){			//时间复杂度O(log2n)
		m1=(s1+d1)/2;
		m2=(s2+d2)/2;
		if(La.data[m1]==Lb.data[m2])			//两个序列的中位数相等的时候直接退出 
			return La.data[m1];
		if(La.data[m1]>Lb.data[m2]){			//主要是二分的思想逐渐折半然后比较
			if((s1+d1)%2==0){
				s1=m1;
				d2=m2;
			}
			else{
				s1=m1+1;
				d2=m2;
			}
		}
		if(La.data[m1]<Lb.data[m2]){
			if((s2+d2)%2==0){
				d1=m1;
				s2=m2;
			}
			else{
				d1=m1;
				s2=m2+1;
			}
		}
	}
	return La.data[s1]<Lb.data[s2]?La.data[s1]:Lb.data[s2];
} 

第12题:【2013年统考题】找到到顺序表中的主元素,主元素的定义为出现的次数m>n/2,其中n是整个表的长度。
思考:
这个题目我最先想的是统计各个整数出现的个数,找到出现次数最多的数就时候选主元素。统计的话需要占用空间O(n),时间上只要跑两遍就可以了,第一遍统计第二遍比较多少,时间复杂度也是O(n)。但是参考答案只需要O(1)的空间复杂度,就是直接找候选主元素。
思路:
首先设置第一个元素为候选主元素,这个毋庸置疑。然后从第二个元素开始往后比较,相同的话计数count++;不相同的话count–;这里也好懂。**重点 **是当目前的元素与候选主元素不相同的时候,如果count<=0,说明了当前的候选主元素已经个数为0了,就是说每出现一次这个数(假设是num),都会有另外一个不相等的数进行抵消,num到目前的进度的时候达不到1/2.所以这个时候就必须要更换种子选手了,既然能当上种子选手也说明他在前面的序列中,出现的个数也是相当的多了,不然就会有其他的种子选手替换掉他。所以这时候就换下一个选手作为种子选手了。
当count<=0时,更换了种子选手,那么换掉的下一个种子选手可能还没有换之前的多怎么办呢。这个换个角度就能想明白了,既然作为一名种子选手就是想成为主元素的,那么主元素要求就是count>n/2,这就说明,走到最后的时候他能干掉所有其他的种子选手,是就是每出现一个不一样的元素,都能找一个元素给抵消掉,不管小伙伴来的有多晚,都能抵消掉。
看两组样例:
在这里插入图片描述
无论中间的时候种子选手会换给谁当,只要你是主元素,你都能给他们比下去,有这就够了。

int f12(SqList &L){				//找到出现次数大于length/2的元素 
	int i,num;
	int count=1;
	num=L.data[0];				//设置候选主元素为第一个 
	for(i=1;i<L.length;i++){	//查找候选主元素 
		if(L.data[i]==num)
			count++;			//与候选主元素相同则计数+1 
		else{
			if(count>0)			//计数count>0说明当前候选主元素不低于1/2 
				count--;
			else{				//count<0则需要更换候选主元素 
				num=L.data[i];
				count=1;
			}
		}
		cout << i << ":" << count << " " << num << endl;
	}
	if(count>0){					
		count=0;
		for(i=0;i<L.length;i++){	//统计实际出现的次数 
			if(L.data[i]==num)
				count++;
		}
	}
	if(count>L.length/2)
		return num;
	else
		return -1;
}
int  f13(SqList &L){			//时间复杂度O(n),空间:O(n)
	int k=0;
	int  a[n+2];
	int  i;
	memset(a,0,sizeof(a));
	for(i=0;i<L.length;i++){	//找到最小的未出现的正整数
		a[L.data[i]]++;
	}
	for(i=1;i<=n+1;i++){
		if(a[i]==0)
			return i;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
综合试题及答案,帮助大家更好的复习.25、用一组地址连续的存储单元存放的元素一定构成线性表。( ) A ) 平均情况下,快速排序法最快,堆积排序法最节省空间 若线性表采用顺序存储结构,每个数据元素占用4个存储单元,第12个数据元素的存储地址为144,则第1个数据元素的存储地址是101。Loc(ai)=locl+(i—1)( ) 若长度为n的线性表采用顺序存储结构,删除表的第i个元素之前需要移动表中n-i+1个元素。( )【这是插入的,删除的n-i】 确定串T在串S中首次出现的位置的操作称为串的模式匹配。( 深度为h的非空二叉树的第i层最多有2i-1 个结点。 散列表的查找效率主要取决于所选择的散列函数与处理冲突的方法。 稀疏矩阵压缩存储后,必会失效掉随机存取功能 若一个有向图的邻接矩阵中,对角线以下元素均为0,则该图的拓扑有序序列必定存在。( ) 二叉树可以用0≤度≤2的有序树来表示。 非空双向循环链表中由q所指的结点后面插入一个由p指的结点的动作依次为:p->prior=q, p->next=q->next,q->next=p,q->prior->next←p。( ) 删除非空链式存储结构的堆栈(设栈顶指针为top)的一个元素的过程是依次执行:p=top,top= p->next,free (p)。( ) 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列。( ) 在索引顺序表上实现分块查找,在等概率查找情况下,其平均查找长度不与表的个数有关,而与每一块中的元素个数有关 无向图的邻接矩阵是对称的有向图的邻接矩阵是不对称的。( _ D _ C B D D C C A B ( C A B D D C B. C C D 如果某图的邻接矩阵是对角线元素均为零的上三角矩阵,则此图是 D D D C A D A D D B A D A B D B C B ( D A B D C 6___ ( C D D __ C A B D 针q所指 C A A D A D B  D A② D A、 )的有限集合 C _B A  C A  C A D ( D C A D B ( B D ( D _ A A ) ( C A ( B ( B D 只有在初始数据为逆序时,冒泡排序所执行的比较次数最多。(

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值