数据结构与算法-题解与模板(图、查找、排序)

第七章-图

模板-DFS

 void DFS(MatGraph g,int v)
{
	cout<<v<<' ';
	visited[v]=1;
	for(int w=0;w<g.n;w++)
	{
		if(g.edges[v][w]!=0&&g.edges[v][w]!=INF&&visited[w]==0)
			DFS(g,w);
	}
}

模板-BFS

void BFS(MatGraph g,int v)
{
	int w,visited[MAXVEX];
	int Qu[MAXVEX],front=0,rear=0;
	for(int i=0;i<g.n;i++)
		visited[i]=0;
	cout<<v<<' ';//访问节点v
	visited[v]=1;
	rear =(rear=1)%MAXVEX;
	Qu[rear]=v;
	while(front!=rear)
	{
		front = (front+1)%MAXVEX;
		w=Qu[front];
		for(int i=0;i<g.n;i++)
		{
			if(g.edges[w][i]!=0 && g.edges[w][i]!=INF && visited[i]==0)
			{
				cout<<i<<' ';//访问节点i
				visited[i]=1;
				rear=(rear+1)%MAXVEX;
				Qu[rear]=i;
			}
		}
	}
}

A01:选择题 - 图1

一个无向图中有16条边,度为4的顶点有3个,度为3的顶点有4个,其余顶点的度均小于3,则该图至少有( 11 )个顶点。

A02:选择题 - 图2

已知一个有向图的邻接矩阵表示,要删除所有从第i个结点发出的边,应如何操作( D)。

A. 将邻接矩阵的第i行删除 B. 将邻接矩阵的第i列元素全部置为0 C. 将邻接矩阵的第i列删除 D. 将邻接矩阵的第i行元素全部置为0

A03:无向图的邻接矩阵

#include<iostream>
using namespace std;
#define MAX 100
typedef int VertexType[10];

typedef struct vertex
{
	int adjves;
	VertexType data;
}VType;
typedef struct graph
{
	int n,e;
	VType vexs[MAX];        //点
	int edges[MAX][MAX];	//边
}MatGraph;

void CreateGraph(MatGraph &g,int A[][MAX],int n,int e)//建立 
{
	g.n=n;g.e=e;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			g.edges[i][j]=A[i][j];
}

void DisGraph(MatGraph g)//输出 
{
	for(int i=0;i<g.n;i++)
	{
		for(int j=0;j<g.n;j++)
			if(g.edges[i][j]!=0)
				cout<<g.edges[i][j]<<" ";
			else
				cout<<"-1"<<" ";
		cout<<endl;
	}
}

int main()
{
	int M,N;
	MatGraph g;
	cin>>N>>M;
	int a,b,c;
	int B[MAX][MAX];
	for(int i=0;i<M;i++)
	{
		cin>>a>>b>>c;
		B[a-1][b-1]=c;
		B[b-1][a-1]=c;
	}
	CreateGraph(g,B,N,M);
	DisGraph(g);
}



A04:第七章 实验题 7.3 深度优先遍历练习

#include<iostream>
using namespace std;
#define MAXVEX 100
#define INF 100000000
typedef char VertexType[10];
int visited[10];
typedef struct vertex
{
	int adjvex;
	VertexType data;
}VType;
typedef struct graph
{
	int n,e;
	VType vexs[MAXVEX];          //点
	int edges[MAXVEX][MAXVEX];   //边
}MatGraph;

void CreateGraph(MatGraph &g,int A[][MAXVEX],int n,int e)//建立 
{
	g.n=n;g.e=e;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			g.edges[i][j]=A[i][j];
}

void DispGraph(MatGraph g)
{
	for(int i=0;i<g.n;i++)
	{
		for(int j=0;j<g.n;j++)
		{
			if(g.edges[i][j]<INF)
				cout<<g.edges[i][j]<<"    ";
			else cout<<-1<<"    ";
		}
		cout<<endl;
	}
} 
 
void DFS(MatGraph g,int v)
{
	cout<<v<<' ';
	visited[v]=1;
	for(int w=0;w<g.n;w++)
	{
		if(g.edges[v][w]!=0&&g.edges[v][w]!=INF&&visited[w]==0)
			DFS(g,w);
	}
}

int main()
{
	MatGraph g;
	int n=7,e=12,v;
	int A[MAXVEX][MAXVEX]={{0,2,5,3,0,0,0},
							{0,0,2,0,0,8,0},
							{0,0,0,1,3,5,0},
							{0,0,0,0,5,0,0},
							{0,0,0,0,0,3,9},
							{0,0,0,0,0,0,5},
							{0,0,0,0,0,0,0}};
	CreateGraph(g,A,n,e);
	for(int i=0;i<g.n;i++)
		visited[i]=0;
	cin>>v;
	DFS(g,v);
}


A05:第七章 实验题 7.3 广度优先遍历练习

#include<iostream>
using namespace std;
#define MAXVEX 100
#define INF 100000000
typedef char VertexType[10];

typedef struct vertex
{
	int adjvex;
	VertexType data;
}VType;
typedef struct graph
{
	int n,e;
	VType vexs[MAXVEX];
	int edges[MAXVEX][MAXVEX];
}MatGraph;

void CreateGraph(MatGraph &g,int A[][MAXVEX],int n,int e)//建立 
{
	g.n=n;g.e=e;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			g.edges[i][j]=A[i][j];
}
void BFS(MatGraph g,int v)
{
	int w,visited[MAXVEX];
	int Qu[MAXVEX],front=0,rear=0;
	for(int i=0;i<g.n;i++)
		visited[i]=0;
	cout<<v<<' ';//访问节点v
	visited[v]=1;
	rear =(rear=1)%MAXVEX;
	Qu[rear]=v;
	while(front!=rear)
	{
		front = (front+1)%MAXVEX;
		w=Qu[front];
		for(int i=0;i<g.n;i++)
		{
			if(g.edges[w][i]!=0 && g.edges[w][i]!=INF && visited[i]==0)
			{
				cout<<i<<' ';//访问节点i
				visited[i]=1;
				rear=(rear+1)%MAXVEX;
				Qu[rear]=i;
			}
		}
	}
}

int main()
{
	MatGraph g;
	int n=7,e=12,v;
	int A[MAXVEX][MAXVEX]={{0,2,5,3,0,0,0},
							{0,0,2,0,0,8,0},
							{0,0,0,1,3,5,0},
							{0,0,0,0,5,0,0},
							{0,0,0,0,0,3,9},
							{0,0,0,0,0,0,5},
							{0,0,0,0,0,0,0}};
	CreateGraph(g,A,n,e);
	cin>>v;
	BFS(g,v);
}

A06:prim算法求最小生成树

处理点(两个集合搭桥)

#include<iostream>
using namespace std;
#define MAXVEX 100
#define INF 100000000
typedef char VertexType[10];

typedef struct vertex
{
	int adjvex;
	VertexType data;
}VType;
typedef struct graph
{
	int n,e;
	VType vexs[MAXVEX];
	int edges[MAXVEX][MAXVEX];
}MatGraph;

void CreateGraph(MatGraph &g,int A[][MAXVEX],int n,int e)//建立 
{
	g.n=n;g.e=e;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			g.edges[i][j]=A[i][j];
}

void Prim(MatGraph g,int v)
{
	int lowcost[MAXVEX];
	int closest[MAXVEX];
	int min,k;
	for(int i=0;i<g.n;i++)
	{
		lowcost[i]=g.edges[v][i];
		closest[i]=v;
	}
	for(int i=1;i<g.n;i++)
	{
		min = 100;k=-1;
		for(int j=0;j<g.n;j++)
		{
			if(lowcost[j]!=0 && lowcost[j]<min)
			{
				min = lowcost[j];
				k=j;
			}
		}
		cout<<min<<' ';
		lowcost[k]=0;
		for(int j=0;j<g.n;j++)
		{
			if(lowcost[j]!=0 && g.edges[k][j]<lowcost[j])
			{
				lowcost[j]=g.edges[k][j];
				closest[j]=k;
			}
		}
	}
}

int main()
{
	MatGraph g;
	int n,e,v=0;
	cin>>n>>e;
	int A[MAXVEX][MAXVEX];
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			cin>>A[i][j];
	CreateGraph(g,A,n,e);
	Prim(g,v);
}

A07:dijkstra求最短路径

#include <iostream>
#include <stack>
#include <stdio.h>
using namespace std;
#define MAXVEX 100 
#define INF 1e9
int path[MAXVEX][MAXVEX]; 
int A[MAXVEX][MAXVEX];
typedef char VertexType[10];
typedef struct vertex {
    int adjvex; 
    VertexType data; 
} VType;
typedef struct graph {
    int n, e; 
    VType vexs[MAXVEX]; 
    int edges[MAXVEX][MAXVEX]; 
} MatGraph; 

void CreateGraph(MatGraph& g, int As[][MAXVEX], int n, int e)
{
    int i, j;
    g.n = n;
    g.e = e;
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            g.edges[i][j] = As[i][j];
}
void Floyd(MatGraph g) 
{
    int i, j, k;
    for (i = 0; i < g.n; i++) 
        for (j = 0; j < g.n; j++) {
            A[i][j] = g.edges[i][j];
            if (i != j && g.edges[i][j] < INF)
                path[i][j] = i; 
            else
                path[i][j] = -1;
        }
    for (k = 0; k < g.n; k++) 
    {
        for (i = 0; i < g.n; i++)
            for (j = 0; j < g.n; j++)
                if (A[i][j] > A[i][k] + A[k][j]) 
                {
                    A[i][j] = A[i][k] + A[k][j];
                    path[i][j] = path[k][j];
                }
    }
}

int main()
{
    int v, a;
    scanf("%d%d", &v, &a);
    int s, e;
    scanf("%d%d", &s, &e);
    int m[v][100];
    for (int i = 0; i < v; i++) {
        for (int j = 0; j < v; j++) {
            if (j == i) {
                m[i][j] = 0;
            } else
                m[i][j] = INF;
        }
    }
    for (int i = 0; i < a; i++) {
        int b, d, f;
        scanf("%d%d%d", &b, &d, &f);
        m[b][d] = f;
    }
    MatGraph G;
    stack<int> ss;
    CreateGraph(G, m, v, a);
    Floyd(G);
    if (A[s][e] == INF) {
        printf("no answer\n");
        return 0;
    }
    cout << A[s][e] << endl;
    ss.push(e);
    while (e != s) {
        ss.push(path[s][e]);
        e = path[s][e];
    }
    while (!ss.empty()) {
        cout << 'v' << ss.top() << ' ';
        ss.pop();
    }
    return 0;
}

第八章-查找

二分查找

int BirarySearch(int R[],int key,int n)
{
	int low=0,high=n-1,mid,count=0;
	while(low<=high)
	{
		count++;
		mid=(low+high)/2;
		if(R[mid]==key)
		{
			return count;//返回查找次数
		}
		else if(R[mid]>key)
			high=mid-1;
		else 
			low=mid+1;
	}
	return -1;
}

02:Ch8-1-2 整数序列折半查找

已知整数序列为2,4,7,9,10,14,18,26,32,40,设计整数递增有序顺序表的折半查找程序,并用相关数据进行测试。

其中第一个整数编号为1,第二个为2,依次类推。

#include<iostream>
using namespace std;
int a[10]={2,4,7,9,10,14,18,26,32,40};
int BF(int k,int &time){
	int l=0,r=10-1,mid;
	while(l<=r){
		time++;
		mid=(l+r)/2; 
		if(a[mid]==k) return mid+1;
		else if(a[mid]>k){
			r=mid-1;
		}
		else{
			l=mid+1;
		}
	} 
	return 0;
}

int main(){
	int key;
	cin>>key;
	int time=0;
	int ans=BF(key,time);
	cout<<key<<" "<<ans<<" "<<time<<endl;
	
} 

03:第八章课后实验题描述

递增序列a中元素各不相同(元素个数不超过20个)。高效算法判定是否存在整数i在a[i]

输入

第一行为元素个数n,第二行,为空格分隔的整数n个序列

输出

若存在,显示:exist;若不存在,则输出显示:non-exist

2-2递增序列判断是否存在a[j]=j

#include<iostream>
using namespace std;

typedef int ElemType;
typedef int KeyType;
typedef struct
{
	KeyType Key;
	ElemType data;
}SqType;

int SqSearch(SqType R[],int n)
{
	int i=0;
	while(i<n && R[i].Key!=i)
		i++;
	if(i>=n)
		return 0;
	else
		return i+1;
}

int main()
{
	int n;
	cin>>n;
	SqType a[20];
	for(int i=0;i<n;i++)
		cin>>a[i].Key;
	if(SqSearch(a,n)!=0)
		cout<<"exist";
	else 
		cout<<"non-exist";
}

04:两个等长升序序列计算中位数

计算整数序列A、B的中位数,两个序列等长且均为升序,每个序列最多20个整数。 设计尽可能高效算法实现中位数计算。

注1:长为L(L>=1)的升序序列中位数为位置序号为ceil(L/2)的元素值,其中ceil(x)返回大于或等于x的最小整数

注2:两个升序序列的中位数是将两个序列后合并后升序序列的中位数。

#include<iostream>
#include<algorithm>
using namespace std;


int main()
{
	int n;
	cin>>n;
	int a[2*n];
	for(int i=0;i< 2*n;i++){
		cin>>a[i];
	}
	sort(a,a+2*n);
	cout<<a[n-1]<<endl;
}

06:Ch8-2-3

已知一个递增序列a[1…4n],假设所有整数均不相同。将按如下方法查找一个为b的整数:先在编号为4、8、12、16…4n的元素中进行顺序查找,或者查找成功,或者由此确定一个继续进行折半查找的范围。

设定整数序列为a={1,2,3,4,10,11,12,13,20,21,22,23,30,31,32,33,52,53,54,55},第一个元素序号为1,第二个为2,依次类推。

设计满足上述过程的查找算法.

 #include<iostream>
using namespace std;

typedef int ElemType;
typedef int KeyType;
typedef struct
{
	KeyType Key;
	ElemType data;
}SqType;
typedef struct
{
	KeyType Key;
	int low,high;
}IdxType;

int BlkSearch(SqType R[],int n,IdxType I[],int b,KeyType k)
{
	int low=0,high = b-1,mid,i;
	while(low<high)
	{
		mid = (low+high)/2;
		if(I[mid].Key<k)
			low=mid+1;
		else
			high=mid;
	}
	i = I[high].low;
	while(i<=I[high].high && R[i].Key != k)
		i++;
	if(i<=I[high].high)
		return i+1;
	else
		return 0;
}

int main()
{
	SqType R[100];
	IdxType I[100];

	I[0].Key=4;I[1].Key=13;I[2].Key=23;I[3].Key=33;I[4].Key=55;
	
	R[0].Key=1;R[1].Key=2;R[2].Key=3;R[3].Key=4;R[4].Key=10;
	R[5].Key=11;R[6].Key=12;R[7].Key=13;R[8].Key=20;R[9].Key=21;
	R[10].Key=22;R[11].Key=23;R[12].Key=30;R[13].Key=31;R[14].Key=32;
	R[15].Key=33;R[16].Key=52;R[17].Key=53;R[18].Key=54;R[19].Key=55;
	
	int m,n=20,b=5;
	I[0].high=3;I[1].high=7;I[2].high=11;I[3].high=15;I[4].high=19;
	I[0].low=0;I[1].low=4;I[2].low=8;I[3].low=12;I[4].low=16;
	cin>>m;
	int a[100];
	for(int i=0;i<m;i++)
		cin>>a[i];
	for(int i=0;i<m;i++)
	{
		int s=BlkSearch(R,n,I,b,a[i]);
		if(s==0)
			cout<<'0'<<endl;
		else
			cout<<"a["<<s<<"]="<<a[i]<<endl;
	}
	return 0;
}

第九章-排序

冒泡排序

for(int i=0;i<n;i++){
    for(int j=0;j<n-i-1;j++){
         if(a[j]>=a[j+1]){
            int temp=a[j];
            a[j]=a[j+1];
            a[j+1]=temp;
        }
    }
}

直接插入排序

void InsertSort(SqType R[],int n) //直接插入排序算法 
{
	int j;
	SqType tmp;
	for(int i=1;i<n;i++)
	{
		if(R[i-1].Key<R[i].Key)
		{
			tmp=R[i];
			j=i-1;
			do
			{
				R[j+1]=R[j];
				j--;

			}
			while(j>=0 && R[j].Key<tmp.Key);
			R[j+1]=tmp;
			
		}
		for(int w=0;w<n;w++)
				cout<<R[w].Key<<' ';
			cout<<endl;
	}
}

二分插入排序

void BinInsertSort(SqType R[],int n) 
{
	int low,high,mid;
	SqType tmp;
	for(int i=1;i<n;i++)
	{
		if(R[i-1].Key>R[i].Key)
		{
			tmp=R[i];
			low=0;high=i-1;
			while(low<=high)
			{
				mid = (low+high)/2;
				if(tmp.Key<R[mid].Key)
					high=mid-1;
				else
					low=mid+1;
			}
			for(int j=i-1;j>=high;j--)
				R[j+1]=R[j];
			R[high+1]=tmp;
		}
		for(int w=0;w<n;w++)
			cout<<R[w].Key<<' ';
		cout<<endl;
	}
}

快速排序

// 补充以下快速排序函数代码,使得输入参数desc为0时实现升序,desc为1时实现降序
void QuickSort(SqType R[], int s, int t, int desc)
{
	int i = t, j = s;
	SqType tmp;
	if (s < t) {
	 	if(desc==0)//升序快排
	 	{	
		 	tmp=R[s];
		 	while(j!=i)
			{
				while(i>j && R[i].key>=tmp.key)
					i--;
				R[j]=R[i];
				while(j<i && R[j].key<=tmp.key)
					j++;
				R[i]=R[j];
			}
			R[j]=tmp;	
		}
		else//降序快排
		{
			tmp=R[s];
			while(i!=j)
			{
				while(i>j && R[i].key<=tmp.key)
					i--;
				R[j]=R[i];
				while(j<i && R[j].key>=tmp.key)
					j++;
				R[i]=R[j];
			}
			R[j]=tmp;	
		}
		QuickSort(R, s, i - 1, desc);
		QuickSort(R, i + 1, t, desc);
	}
}

05:算法实现 - 排序

使用任意一种排序算法对输入序列进行排序,将其中元素数值域为单数进行升序排序和元素数值域为偶数的按照降序排序

// 补充以下快速排序函数代码,使得输入参数desc为0时实现升序,desc为1时实现降序
void QuickSort(SqType R[], int s, int t, int desc)
{
	int i = t, j = s;
	SqType tmp;
	if (s < t) {
	 	if(desc==0)
	 	{	
		 	tmp=R[s];
		 	while(j!=i)
			{
				while(i>j && R[i].key>=tmp.key)
					i--;
				R[j]=R[i];
				while(j<i && R[j].key<=tmp.key)
					j++;
				R[i]=R[j];
			}
			R[j]=tmp;	
		}
		else
		{
			tmp=R[s];
			while(i!=j)
			{
				while(i>j && R[i].key<=tmp.key)
					i--;
				R[j]=R[i];
				while(j<i && R[j].key>=tmp.key)
					j++;
				R[i]=R[j];
			}
			R[j]=tmp;	
		}
QuickSort(R, s, i - 1, desc);
QuickSort(R, i + 1, t, desc);
	}
}

08:冒泡+二分查找

描述

有一组数据放在数组R[ ]中,R[ ]={9,8,7,6,0,-1,10,-5,-32,66},请调用冒泡排序函数(自己定义函数),先将数组进行排序,然后调用二分查找算法(自己定义函数)查找某数,分别给出比较次数,每个比较次数占一行,比较次数为-1时表示没找到。

输入

第1行输入排序标志,为1时,对原数组先采用升序排序,为2时,对原数组采用降序排序。第2行开始输入待查找的数。输入非整数或^Z时,结束输入。

输出

采用二分查找法查找某数时的比较次数,每个比较次数占一行,比较次数为-1时表示没找到。

#include<iostream>
using namespace std;

void BS1(int R[]){
	for(int i=0;i<10;i++){
		for(int j=0;j<10-i-1;j++){
			if(R[j]>R[j+1]){
				int temp=R[j];
				R[j]=R[j+1];
				R[j+1]= temp;
			}
		}
	}
}
void BS2(int R[]){
	for(int i=0;i<10;i++){
		for(int j=0;j<10-i-1;j++){
			if(R[j]<R[j+1]){
				int temp=R[j];
				R[j]=R[j+1];
				R[j+1]=temp;
			}
		}
	}
}
int cheak1(int R[],int k,int n)
{
	int low=0,high=n-1,mid,i=0;
	while(low<=high)
	{
		i++;
		mid=(low+high)/2;
		if(R[mid]==k)
		{
			return i;
		}
		else if(R[mid]>k)
			high=mid-1;
		else 
			low=mid+1;
	}
	return -1;
}

int cheak2(int R[],int k,int n)
{
	int low=0,high=n-1,mid,i=0;
	while(low<=high)
	{
		i++;
		mid=(low+high)/2;
		if(R[mid]==k)
		{
			return i;
		}
		else if(R[mid]<k)
			high=mid-1;
		else 
			low=mid+1;
	}
	return -1;
}
int main(){
	int  R[10]={9,8,7,6,0,-1,10,-5,-32,66};
	int n=10;
	int tape;
	cin>>tape;
	if(tape==1) BS1(R);
	else  BS2(R);
	
	int x;
	while(cin>>x)
	{
		int ci;
		if(tape==1)
		{
			ci=cheak1(R,x,10);
			cout<<ci<<endl;
		}
			
		else
		{
			ci=cheak2(R,x,10);
			cout<<ci<<endl;
		}	
	}
	system("pause");
	return 0;
}

09:顺序表(无序)二路归并找成绩排名

#include <stdio.h>
#define MAXSIZE 255 

typedef int ElemType;
			
typedef struct 
{	ElemType stu_score[MAXSIZE];		
	int length;					
} StuSqList;			
			
void InitList(StuSqList &L)	
{
	L.length=0;
}
void DestroyList(StuSqList L)
{
}

void CreateList(StuSqList &L,ElemType a[],int n)
{
	int i,k=0;						
	for (i=0;i<n;i++)
	{
		L.stu_score[k]=a[i];				
		k++;						
	}
	L.length=k;						
}

//下面补充需要的函数,实现对成绩表的排序和查找排名为k的成绩
// 在此处补充你的代码
int Topk(StuSqList A,StuSqList B,int k,ElemType &e)
{
	//输入代码	
	for(int i=0;i<A.length-1;i++){
		for(int j=0;j<A.length-i-1;j++){
			if(A.stu_score[j]<A.stu_score[j+1]){
				int temp=A.stu_score[j];
				A.stu_score[j]=A.stu_score[j+1];
				A.stu_score[j+1]= temp;
			}
		}
	}
	for(int i=0;i<B.length-1;i++){
		for(int j=0;j<B.length-i-1;j++){
			if(B.stu_score[j]<B.stu_score[j+1]){
				int temp=B.stu_score[j];
				B.stu_score[j]=B.stu_score[j+1];
				B.stu_score[j+1]= temp;
			}
		}
	}
	for(int i=0;i<A.length ;i++){
		printf("%d ",A.stu_score[i]);
	}
	printf("\n");
	for(int i=0;i<B.length ;i++){
		printf("%d ",B.stu_score[i]);
	}
	printf("\n");
	StuSqList C;
	ElemType d[MAXSIZE];
	int w;
	w=A.length+B.length;
	CreateList(C,d,w);
	int i=0,j=0,t=0;
	while(i<A.length && j<B.length)
	{
		if(A.stu_score[i]>B.stu_score[j])
		{
			C.stu_score[t]=A.stu_score[i];
			i++;t++;
		}
		else
		{
			C.stu_score[t]=B.stu_score[j];
			j++;t++;
		}
	}
	while(i<A.length)
	{
		C.stu_score[t]=A.stu_score[i];
		i++;t++;
	}
	while(j<B.length)
	{
		C.stu_score[t]=B.stu_score[j];
		j++;t++;
	}
	C.length=t;
	
	if(k<=0 || k>=t+1) return 0;
	else
	{
		e=C.stu_score[k-1];
		return 1;
	}
	//输入代码	
}

//上面补充需要的函数,实现对成绩表的排序和查找排名为k的成绩

int main()
{
	StuSqList L1,L2;
	ElemType a[MAXSIZE];
	int n, m;

	scanf("%d %d",&n, &m);
	
	for (int i=0;i<n;i++)	scanf("%d",&a[i]);
	CreateList(L1,a,n);

	for (int i=0;i<m;i++)	scanf("%d",&a[i]);
	CreateList(L2,a,m);

	ElemType e;
	int k;
	scanf("%d",&k);

	if (Topk(L1,L2,k,e))
		printf("%d %d",k,e);
	else
		printf("k=%d err",k);
	
	DestroyList(L1);
	DestroyList(L2);
}

其他例题

QM20_奇偶快速排序

输入n个整数,彼此以空格分隔

重新排序以后输出(也按空格分隔),要求:

1.先输出其中的奇数,并按从小到大排列;

2.然后输出其中的偶数,并按从大到小排列;

3.使用快速排序算法

#include <iostream>
using namespace std;

#define MAX_SIZE 10002
typedef int KeyType;
typedef int ElemType;
typedef struct {	
	KeyType key;
	ElemType data;
} SqType;

void DispList(SqType ar[],int n)
{
	for (int i=0; i<n; i++) 
		cout << ar[i].key <<" ";
	cout<<endl;
}
///
void QuickSort(SqType R[], int s, int t, int desc)
{
	int i = t, j = s;
	SqType tmp;
	if (s < t) {
		tmp = R[s];
		while (i != j)
		{
			if (desc == 0)
			{
				while (j < i && R[i].key >= tmp.key)
					i--;
				R[j] = R[i];
				while (j < i && R[j].key <= tmp.key)
					j++;
				R[i] = R[j];
			}
			else
			{
				while (j < i && R[i].key <= tmp.key)
					i--;
				R[j] = R[i];
				while (j < i && R[j].key >= tmp.key)
					j++;
				R[i] = R[j];
			}

		}
		R[i] = tmp;
		QuickSort(R, s, i - 1, desc);
		QuickSort(R, i + 1, t, desc);
	}
}
void MySort(SqType R[], int n)
{
	SqType a[MAX_SIZE];
	SqType b[MAX_SIZE];
	int an = 0, bn = 0;
	for (int i = 0; i < n; i++) {//奇偶分开
		if (R[i].data % 2 == 0) {
			a[an].key = a[an].data = R[i].data;
			an++;
		}
		else {
			b[bn].key = b[bn].data = R[i].data;
			bn++;
		}
	}
	QuickSort(b, 0, bn - 1, 0);//奇数升序
	QuickSort(a, 0, an - 1, 1);//偶数降序
	for (int i = 0; i < bn; i++)//再放进去
	{
		R[i].key = R[i].data = b[i].key;
	}
	for (int i = 0; i < an; i++)
	{
		R[i  + bn].key = R[i  + bn].data = a[i].key;
	}
}

int main()
{
	SqType ar[MAX_SIZE];
	int n,m;
	cin >> n;
	for (int i=0; i<n; i++) 
	{
		cin >> m;	
		ar[i].key = ar[i].data = m;
	}
	MySort(ar,n);
	DispList(ar,n);
	return 0;
}

QM20_折半查找并删除指定元素

对于一个正整数有序顺序表L,完成下述操作:

(1)首先根据数组a[ ]的值对该顺序表L进行创建,然后将该顺序表L输出;

(2)当用户输入一个正整数m时,如果m在该顺序表L中,则将L中与m值相等的正整数元素删除(包括重复元素),并输出“found”,如果用户输入m与顺序表L中的值都不相等,输出“not found“,保留原L;

(3)最后输出目前的L。

注:BinSearch()函数为采用折半查找法在L中查找值为m的元素,如果输入m在顺序表L中,则输出“found”,否则输出“not found”;

​ Del( )函数为在L中删除值为i的元素。

#include <stdio.h>
#include<iostream>
using namespace std;
#define MaxSize 100
typedef int ElemType;				
typedef struct
{	ElemType data[MaxSize];			
	int length;						
} SqList;
void DestroyList(SqList L)			
{
}
void DispList(SqList L)				
{	int i;
	for (i=0;i<L.length;i++)
		printf("%d ",L.data[i]);
	printf("\n");
}
void CreateList(SqList &L,ElemType a[],int n)	
{
	int i,k=0;						
	for (i=0;i<n;i++)
	{
		L.data[k]=a[i];				
		k++;						
	}
	L.length=k;						
}
// 在此处补充你的代码//
int BinSearch(SqList& L, int n, int m)
{
	int low = 0, high = n - 1, mid;
	while (low <= high)
	{
		mid = (low + high) / 2;
		if (L.data[mid] == m)//找到了
		{
			cout << "found" << endl;
			return mid + 1;
		}
			
		else if (L.data[mid] > m)
			high = mid - 1;
		else
			low = mid + 1;
	}
	cout << "not found" << endl;
	return 0;
}
void Del(SqList& L, int i)		
{
	int j;
	int m = L.data[i - 1];
	for (int k = 0; k < L.length; k++)
	{
		if (L.data[k] == m)//找到了要删除的元素
		{
			for (j = k+1; j < L.length; j++)//覆盖删除
				L.data[j - 1] = L.data[j];
			L.length--;
			k--;
		}
	}						
}


int main()
{
	SqList L;
	int a[]={1,2,2,2,3,5,5,5,10,23,88};
	int n=sizeof(a)/sizeof(a[0]);
	int m,i;
	CreateList(L,a,n);
	cin>>m;
	DispList(L);
	i=BinSearch(L,n,m);   
	if(i>0)
	  Del(L,i);
	DispList(L);
	DestroyList(L);
}

QM20_单链表操作

设计一个算法在带头结点的非空单链表L中找到最小值结点(假定当前链表最小值唯一),并在最小值之前插入一个值为x的结点。

#include <malloc.h>
#include <iostream>
using namespace std;

typedef int ElemType;
#define MAX_SIZE 100

typedef struct node
{
	ElemType data;		//数据域
	struct node *next;	//指针域
} SLinkNode;	//单链表结点类型

void CreateListR(SLinkNode *&L, ElemType a[], int n)//尾插法建表
{
	SLinkNode *s, *tc;  int i;
	L = (SLinkNode *)malloc(sizeof(SLinkNode));	
	tc = L;				
	for (i = 0; i < n; i++)
	{
		s = (SLinkNode *)malloc(sizeof(SLinkNode));
		s->data = a[i];				
		tc->next = s;		
		tc = s;
	}
	tc->next = NULL;		
}
// 在此处补充你的代码//

int Insertbeforex(SLinkNode*& L, ElemType x)
{
	if (L->next == NULL)
		return 0;
	SLinkNode* maxpre = L;
	SLinkNode* maxp = L->next;
	SLinkNode* pre = maxp;
	SLinkNode* p = maxp->next;
	while (p != NULL) {
		if (maxp->data > p->data) {
			maxpre = pre;
			pre = p;
			maxp = p;
			p = p->next;
		}
		else {
			pre=p;
            p=p->next;
		}
	}
	SLinkNode* q;
	q = (SLinkNode*)malloc(sizeof(SLinkNode));
	q->data = x;
	q->next = maxpre->next;
	maxpre->next = q;
	return 1;
}


///
void DispList(SLinkNode *L)	//输出单链表
{
	SLinkNode *p = L->next;
	while (p != NULL)
	{
		cout<<p->data<<" ";
		p = p->next;
	}
	cout<<endl;
}
void DestroyList(SLinkNode *&L)	//销毁单链表L
{
	SLinkNode *pre = L, *p = pre->next;
	while (p != NULL)
	{
		free(pre);
		pre = p; p = p->next;			
	}
	free(pre);
}
int main()
{	
	ElemType a[MAX_SIZE];	
	SLinkNode *L;
	int nlength,x;
	cin >> nlength;
	for (int i = 0; i < nlength; i++) 
		cin >> a[i];
	CreateListR(L, a, nlength);
	cin>>x;
	Insertbeforex(L,x);
	DispList(L);
	DestroyList(L);
	return 0;
	
}

QM20_7的倍数和含7的数游戏

链表中存放有N个不同的数值(100以内),要求编程实现将链表中7的倍数或者含有7的数字删除的功能。

#include<iostream>
#include<stdlib.h>
using namespace std;

#define MAXSIZE 100

typedef int ElemType;
typedef struct node {
	ElemType data;
	struct node *next;
} SLinkNode;

void InitList(SLinkNode *&L)
{
	L = (SLinkNode *)malloc(sizeof(SLinkNode));
	L->next = NULL;
}

void DispList(SLinkNode *L)
{
	SLinkNode *p = L->next;
	while (p != NULL) {
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}

void DestroyList(SLinkNode *&L)
{
	SLinkNode *pre = L, *p = pre->next;
	while (p != NULL) {
		free(pre);
		pre = p;
		p = p->next;
	}
	free(pre);
}

void CreateList(SLinkNode *&L, ElemType a[], int n)
{
	SLinkNode *tc = L;
	for (int i=0; i<n; i++) {
		SLinkNode *s = (SLinkNode *)malloc(sizeof(SLinkNode));
		s->data = a[i];
		tc->next = s;
		s->next = NULL;
		tc = s;
	}
}
//
void DelAll7(SLinkNode*& L)
{
	if (L->next == NULL)
		return ;
	SLinkNode* p = L->next;
	SLinkNode* r = p->next;
	if ((p->data%7 ==0&& p->data>7) || p->data %10==7|| p->data / 7 == 10 || (p->data / 7 == 11 && p->data % 7 < 3))
	{
		free(L);
		L = p;
	}

	while (r != NULL) 
	{
		if ((r->data % 7 == 0 && r->data > 7) || r->data % 10 == 7 || r->data / 7 == 10 ||( r->data / 7 == 11&& r->data % 7 <3))
		{
			SLinkNode* k = r;
			r = r->next;
			p->next = r;
			free(k);
		}
		else 
		{
			p = p->next;
			r = r->next;
		}
	}

}
/
int main(void)
{
	SLinkNode *L;
	InitList(L);
	int n;
	ElemType a[MAXSIZE];
	cin >> n;
	for (int i=0; i<n; i++)
		cin >> a[i];
	CreateList(L, a, n);
	DelAll7(L);
	DispList(L);
	DestroyList(L);
	return 0;
}

括号匹配

假设表达式中只包含三种括号:圆括号、方括号和花括号,它们可相互嵌套,如([{}])或({[][()]})等均为正确的格式,而{[]})}或{[()]或([]}均为不正确的格式.

输入一串括号
如果输入的右括号多余,输出:Extra right brackets
如果输入的左括号多余, 输出:Extra left brackets
如果输入的括号不匹配,输出:Brackets not match
如果输入的括号匹配,输出:Brackets match

输入

{{{{)))

#include <iostream>
#include <cstring>
#include <stack> //方便起见,直接用stl里的栈啦
using namespace std;
stack<char> st;
char s[1000];
int main()
{
    cin>>s;
    bool f=1; //用于标记“因为特殊原因结束扫描”
    for(int i=0;i<strlen(s);i++){
        if(s[i]=='('||s[i]=='['||s[i]=='{')
            st.push(s[i]);
        if(s[i]==')'||s[i]==']'||s[i]=='}'){
            if(st.empty()){
                cout<<"Extra right brackets"<<endl;
                f=0; //因为特殊原因结束扫描
                break;
            }
            else{
                int sum=(int)s[i]+(int)st.top(); //用ascii码检验括号是否匹配
                if(sum==123+125||sum==91+93||sum==40+41)
                {
                    st.pop();
                    continue;
                }
                else{
                    cout<<"Brackets not match"<<endl;
                    f=0; //因为特殊原因结束扫描
                    break;
                }
            }
        }
    }
    if(f)
    {
        if(st.empty())
            cout<<"Brackets match"<<endl;
        else
            cout<<"Extra left brackets"<<endl;
    }
    return 0;
}

舞伴问题

假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队。跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴。规定每个舞曲能有一对跳舞者。若两队初始人数不相同,则较长的那一队中未配对者等待下一轮舞曲。现要求写一个程序,模拟上述舞伴配对问题。

#include <iostream>
using namespace std;
int main()
{
    int m,n,k;
    cin>>m>>n>>k;
    
    for(int i=0;i<k;i++)
        cout<<i%m+1<<" "<<i%n+1<<endl;
    return 0;
}

出栈序列统计

栈是常用的一种数据结构,有n个元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列。你已经知道栈的操作有两种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出。现在要使用这两种操作,由一个操作序列可以得到一系列的输出序列。请你编程求出对于给定的n,计算并输出由操作数序列1,2,…,n,经过一系列操作可能得到的输出序列总数。

#include<iostream>
using namespace std;
int cnt=0; // cnt用来记录序列种类数
int n;
//递归开始了嗷
void dfs(int l,int c,int r) //左l,中c,右r,参考下面的图解
{
    if(r==n){ //“出栈元素个数达到n时就计数一次”
        cnt++;
        return; //“这也是递归调用结束的条件”
    }
    if(l)
        dfs(l-1,c+1,r); //“如果可以进栈则进一个元素”
    if(c)
        dfs(l,c-1,r+1); //“如果可以出栈则出一个元素”
}

int main()
{
    cin>>n;
    dfs(n,0,0); //从没有元素入栈开始进行
    cout<<cnt;
    return 0;
}

1:邻接表练习-PD-

void CreateGraph(AdjGraph*& G, int A[][MAXVEX], int n, int e)
//由邻接矩阵数组A、顶点数n和边数e建立图G的邻接矩阵存储结构
{
int i, j;
	ArcNode* p;
	G = (AdjGraph*)malloc(sizeof(AdjGraph));
	G->n = n;
	G->e = e;
	for (i = 0; i < G->n; i++)
		G->adjlist[i].firstarc = NULL;
	for (i = 0; i < G->n; i++)
		for (j = G->n - 1; j >= 0; j--)
			if (A[i][j] > 0 && A[i][j] < INF)
			{
				p = (ArcNode*)malloc(sizeof(ArcNode));
				p->adjvex = j;
				p->weight = A[i][j];
				p->nextarc = G->adjlist[i].firstarc;
				G->adjlist[i].firstarc = p;
			}
}
	void DestroyGraph(AdjGraph * &G)
	{
		int i;
	ArcNode* pre, * p; 
	for (i = 0; i < G->n; i++)
	{
		pre = G->adjlist[i].firstarc;
		if (pre != NULL)
		{
			p = pre->nextarc;
			while (p != NULL)
			{
				free(pre);
				pre = p;
				p = p->nextarc;
			}

			free(pre);
		}
	}
	free(G);
				
}
	int Degree2(AdjGraph* G, int v)
	{
		int i, d1 = 0, d2 = 0, d;
		ArcNode* p;
		if (v < 0 || v >= G->n)
			return -1;
		p = G->adjlist[v].firstarc;
		while (p != NULL)
		{
			d1++;
			p = p->nextarc;
		}
		for (i = 0; i < G->n; i++)
		{
			p = G->adjlist[i].firstarc;
			while (p != NULL)
			{
				if (p->adjvex == v)
					d2++;
				p = p->nextarc;
			}
		}
		d = d1 + d2;
		return d;
}

二叉树的高度和遍历算法

*在下面补充2个函数,功能分别是:(1)求二叉树高度 (2)按左根右次序输出的遍历算法*/
int BTHeight(BTNode* bt)
{
	int lchilddep, rchilddep;
	if (bt == NULL)
		return(0);
	else
	{
		lchilddep = BTHeight(bt->lchild);
		rchilddep = BTHeight(bt->rchild);
		return (lchilddep > rchilddep) ? (lchilddep + 1) : (rchilddep + 1);
	}
		

}

void OrderTree(BTNode* bt)
{
	if (bt != NULL)
	{
		OrderTree(bt->lchild);
		cout << bt->data << " ";
		OrderTree(bt->rchild);
	}
}

快速排序找第k小元素

#include <iostream>
using namespace std;
void QuickSort(int R[], int s, int t)
{
	int i = s, j = t;
	int tmp;
	if (s < t)
	{
		tmp = R[s];
		while (i != j)
		{
			while (j > i && R[j] >= tmp)
				j--;
			R[i] = R[j];
			while (j > i && R[i] <= tmp)
				i++;
			R[j] = R[i];
		}
		R[i] = tmp;
		QuickSort(R, s, i - 1);
		QuickSort(R, i + 1, t);
	}
}
int FindMinK(int a[], int n, int k, int &value)
{
	QuickSort(a, 0, n - 1);
	if (k<1 || k > n)
		return 0;
	else
	{
		value = a[k - 1];
	return 1;
	}
}
int main(int argc, char** argv) {
	int n,k;
	cin>>n;
	int *data = new int[n];
	for(int i =0;i<n;i++)
	{
		cin>>data[i];
	}
	cin>>k;
	int value = 0;
	int res = FindMinK(data,n,k,value);
	if(res == 0)
		cout<<"err"<<endl;
	else
		cout<<value;
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值