数据结构习题10

title

k阶斐波那契数列(严3.32)

time_limit

3000MS

memory_limit

10000KB

description

试利用循环队列编写k阶斐波那契数列中前n+1项 (f(0),f(1),…,f(n))的程序,要求满足:f(n)<=max而f(n+1)>max,其中max为某个约定的常数。(注意:本题所用循环队列的容量仅为k,则在程序执行结束时,留在循环队列中的元素应是所求k阶斐波那契序列中的最后k项 f(n-k+1),…,f(n))。

input

输入常数max,阶数k,用空格隔开。

output

输出k阶斐波那契数列中的最后k项f(n-k+1),…,f(n)。

sample_input

14 2

sample_output

8 13

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
using namespace std;
typedef struct {
	int *data;
	int first, last, k;
}Quene, *PQuene;
void dequene(PQuene p)
{
	p->first = (p->first + 1) % (p->k);
}

void enquene(PQuene p, int x)
{
	int k = p->k;
	p->data[p->last] = x;
	p->last = (p->last + 1) % k;
}

void show(PQuene p)
{
	int i = p->first, k = p->k;
	printf("%d ", p->data[i]);
	i = (i + 1) % k;
	while (i != p->last) {
		printf("%d ", p->data[i]);
		i = (i + 1) % k;
	}
	cout << endl;
}
int main()
{
	PQuene p;
	int m, k, i, tem;
	p = (PQuene)malloc(sizeof(Quene));
	p->first = p->last = 0;
	p->data = (int *)malloc(sizeof(int)*MAXSIZE);
	scanf("%d%d", &m, &p->k);
	k = p->k;
	for (i = 0; i<k; i++) {
		if (i<k - 2)p->data[i] = 0;
		else p->data[i] = 1;
	}
	//show(p);
	while (1) {
		tem = p->data[p->first];
		for (i = (p->first + 1) % k; i != p->last; i = (1 + i) % k) {
			tem += p->data[i];
		}
		if (tem<m) {
			dequene(p);
			enquene(p, tem);
		}
		else break;
	}
	show(p);
	//cout << "Hello world!" << endl;
	return 0;
}

title

循环右移(耿5.2)

time_limit

3000MS

memory_limit

10000KB

description

编写程序,将一维数组A(下标从1开始)中的元素循环右移k位,要求只用一个元素大小的附加存储。

input

第一行输入一维数组A的长度n和循环位移位数k(0<n<100;0<k<100),用空格分开。

第二行输入n个元素。

output

输出循环右移k位后的一维数组。

sample_input

6 3

1 2 3 4 5 6

sample_output

4 5 6 1 2 3

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

int main()
{
	int n, a[100], k, i, j, bgn;
	scanf("%d%d", &n, &k);
	for (i = 0; i<n; i++) {
		scanf("%d", &a[i]);
	}
	k = k % n;
	bgn = n - 1;  //bgn记录开始循环右移的角标
	for (i = 1; i <= k + 1; i++)       //循环右移k次
	{
		for (j = 0; j < n; j++) {
			a[(bgn - j + 1 + n + 1) % (n + 1)] = a[(bgn - j + n + 1) % (n + 1)];  //因为这里有减法操作,所以区域可能会出现负数,所以加上n+1
		}
		bgn = (bgn + 1 + n + 1) % (n + 1);
	}
	//把辅助存储位去除
	for (i = 1; i <= k; i++) {   //左移k次
		a[(k + i) % (n + 1)] = a[(k + i + 1) % (n + 1)];
	}
	for (i = 0; i<n; i++) {
		printf("%d ", a[i]);
	}
	//cout << "Hello world!" << endl;
	return 0;
}

title

以三元组表为存储结构实现矩阵相加(耿5.7)

time_limit

3000MS

memory_limit

10000KB

description

假设稀疏矩阵A和B均以三元组表作为存储结构。试编写矩阵相加的程序,另设三元组表C存放结果矩阵。矩阵大小为m行n列(0<m,n<100)

input

第一行输入t1,t2(0<t1,t2<100) ,t1和t2分别是矩阵A和B中非零元素的个数,后面t1+t2行分别输入A和B中的元素,用三元组表示。

output

输出三元组表C。

sample_input

3 3

1 2 3

3 2 1

3 4 2

1 1 4

3 2 5

3 4 1

sample_output

1 1 4

1 2 3

3 2 6

3 4 3

#include<cstdio>
#include<cstdlib>
typedef int ElemType;
#define MaxSize 10000
#define Maxcow 1000
typedef struct {
	int i, j;
	ElemType e;
}Triple;

typedef struct {
	Triple data[MaxSize];
	int rpos[Maxcow];
	int mu, nu, tu;
}RLSMaxtrix;

void init_triple(RLSMaxtrix *M,RLSMaxtrix *N)
{
	int num[100], cow, i, j;
	scanf_s("%d%d", &M->tu, &N->tu);
	for (i = 1; i <= M->tu; i++) {
		scanf_s("%d%d%d", &M->data[i].i, &M->data[i].j, &M->data[i].e);
	}
	for (i = 1; i <= N->tu; i++) {
		scanf_s("%d%d%d", &N->data[i].i, &N->data[i].j, &N->data[i].e);
	}
	for (i = 1; i <= M->tu; i++) {
		++num[M->data[i].i];
	}
	M->rpos[1] = 1;
	for (i = 2; i < M->mu; i++)
		M->rpos[i] = M->rpos[i - 1] + num[i - 1];
	
	for (i = 1; i <= N->tu; i++) {
		++num[N->data[i].i];
	}
	N->rpos[1] = 1;
	for (i = 2; i < N->mu; i++)
		N->rpos[i] = N->rpos[i - 1] + num[i - 1];
}

void calculate_triple(RLSMaxtrix *M, RLSMaxtrix *N, RLSMaxtrix *Q)
{
	int cow, i=1, j=1, k=1;
	while (i <= M->tu&&j <= N->tu) {
		if (M->data[i].i == N->data[j].i&&M->data[i].j == N->data[j].j) {
			Q->data[k].j = M->data[i].j;
			Q->data[k].i = M->data[i].i;
			Q->data[k].e = M->data[i].e + N->data[j].e;
			if (Q->data[k].e == 0)k--;//******************************结果为0
			i++, j++, k++;
		}
		else if (M->data[i].i > N->data[j].i || (M->data[i].i == N->data[j].i&&M->data[i].j > N->data[j].j)) {
			Q->data[k].j = N->data[j].j;
			Q->data[k].i = N->data[j].i;
			Q->data[k].e = N->data[j].e;
			j++, k++;
		}
		else {
			Q->data[k].j = M->data[i].j;
			Q->data[k].i = M->data[i].i;
			Q->data[k].e = M->data[i].e;
			i++, k++;
		}
	}
	while(i<=M->tu){
		Q->data[k].j = M->data[i].j;
		Q->data[k].i = M->data[i].i;
		Q->data[k].e = M->data[i].e;
		i++, k++;
	}
	while (j <= N->tu) {
		Q->data[k].j = N->data[j].j;
		Q->data[k].i = N->data[j].i;
		Q->data[k].e = N->data[j].e;
		j++, k++;
	}
	k--;
	Q->tu = k;
}

void show_triple(RLSMaxtrix *Q)
{
	int i;
	for (i = 1; i <= Q->tu; i++) {
		printf("%d %d %d\n", Q->data[i].i, Q->data[i].j, Q->data[i].e);
	}
}

int main()
{
	RLSMaxtrix *M, *N, *Q;
	M = (RLSMaxtrix *)malloc(sizeof(RLSMaxtrix));
	N = (RLSMaxtrix *)malloc(sizeof(RLSMaxtrix));
	Q = (RLSMaxtrix *)malloc(sizeof(RLSMaxtrix));
	M->mu = N->mu = Q->mu = M->nu = N->nu = Q->nu = 100;
	init_triple(M, N);
	calculate_triple(M, N, Q);
	show_triple(Q);
	return 0;
}

 

title

以十字链表为存储结构实现矩阵相加(严5.27)

time_limit

3000MS

memory_limit

10000KB

description

以十字链表为存储结构,编写程序,将稀疏矩阵B加到稀疏矩阵A上。

input

第一行输入四个正整数,分别为稀疏矩阵A和稀疏矩阵B的行数m、列数n、稀疏矩阵A的非零元素个数t1和稀疏矩阵B的非零元素个数t2。接下来的t1+t2行三元组表示,其中第一个元素表示非零元素所在的行值,第二个元素表示非零元素所在的列值,第三个元素表示非零元素的值。

output

输出相加后的矩阵三元组。

sample_input

3 4 3 2

1 1 1

1 3 1

2 2 2

1 2 1

2 2 3

sample_output

1 1 1

1 2 1

1 3 1

2 2 5

#include<cstdio>
//#include<iostream>
#include<cstdlib>
//#include<Windows.h>
//#include<conio.h>
//using namespace std;
typedef int ElemType;

typedef struct OLNode {
	int i, j;
	ElemType e;
	OLNode *right, *down;
}OLNode, *OLink;

typedef struct {
	OLink *rhead, *chead;
	int mu, nu, tu;
}CrossList;

void CreateSMatrix(CrossList *M)
{
	OLink p, q;
	int i;
	M->rhead = (OLink*)malloc((M->mu + 1) * sizeof(OLink));
	M->chead = (OLink*)malloc((M->nu + 1) * sizeof(OLink));
	for (i = 0; i < M->mu + 1; i++)M->rhead[i] = NULL;
	for (i = 0; i < M->nu + 1; i++)M->chead[i] = NULL;
	//memset(M->rhead, NULL, M->mu + 1);
	//memset(M->chead, NULL, M->nu + 1);
	for (i = 0; i < M->tu; i++) {
		p = (OLink)malloc(sizeof(OLNode));
		scanf_s("%d%d%d", &p->i, &p->j, &p->e);
		//M->rhead[0] = p;
		//M->rhead[1] = p;
		//cout << M->rhead[0] << M->rhead[1];

		if (M->rhead[p->i] == NULL || M->rhead[p->i]->j > p->j)p->right = M->rhead[p->i], M->rhead[p->i] = p;
		else {
			for (q = M->rhead[p->i]; (q->right) && q->right->j > p->j; q = q->right);
			p->right = q->right;
			q->right = p;
		}
		if (M->chead[p->j] == NULL || M->chead[p->j]->i > p->i)p->down = M->chead[p->j], M->chead[p->j] = p;
		else {
			for (q = M->chead[p->j]; (q->down) && q->down->i > p->i; q = q->down);
			p->down = q->down;
			q->down = p;
		}
	}
}

void AddSMatrix(CrossList *M, CrossList *N)
{
	int i, j;
	OLink *hj, pm, pn, pre, p, q;
	hj = (OLink *)malloc(sizeof(OLink)*(M->nu + 1));
	for (i = 0; i <= M->nu; i++)hj[i] = M->chead[i];
	for (i = 0; i <= M->mu; i++) {
		pm = M->rhead[i], pn = N->rhead[i], pre = NULL;
		for (; pn != NULL; /*pn = pn->right*/) {
			p = (OLink)malloc(sizeof(OLNode));
			*p = *pn;
			if (pm == NULL || pm->j > p->j) {//行插入
				if (pre == NULL)M->rhead[pn->i] = p;
				else pre->right = p;
				p->right = pm;
				pre = p;
				//完成列插入
				if (hj[p->j] == NULL || hj[p->j]->i > p->i) {
					p->down = hj[p->j]; hj[p->j] = p;
				}
				else {
					for (q = hj[p->j]; q->down != NULL && q->down->i < p->i; q = q->down);
					p->down = q->down;
					q->down = p;
				}
				hj[p->j] = p;
				pn = pn->right;
			}
			else if (pm->j < pn->j) {
				pre = pm; pm = pm->right;
			}
			else {
				pm->e += pn->e;
				if (pm->e == 0) {
					if (pre == NULL)M->rhead[p->i] = pm->right;
					else { pre->right = pm->right; }
					p = pm;	//用于下面的删除
					pm = pm->right;

					if (M->chead[p->j] == p) {
						M->chead[p->j] = hj[p->j] = p->down;
						//pn = pn->right;
					}
					else {
						for (q = hj[p->j]; q->down != NULL && q->down->i < p->i; q = q->down);
						hj[p->j] = q;
						hj[p->j]->down = p->down;
						free(p);
					}
				}
				pn = pn->right;
			}
		}
	}
}

void printSMatrix(CrossList *M)
{
	int i;
	OLink p;
	for (i = 0; i <= M->mu; i++) {
		for (p = M->rhead[i]; p != NULL; p = p->right) {
			printf("%d %d %d\n", p->i, p->j, p->e);
			//if ((i != M->mu) || p->right != NULL)printf("\n");
		}
	}
}

int main()
{
	CrossList *M, *N;
	M = (CrossList *)malloc(sizeof(CrossList));
	N = (CrossList *)malloc(sizeof(CrossList));
	scanf_s("%d%d", &M->mu, &M->nu);
	N->mu = M->mu, N->nu = M->nu;
	scanf_s("%d%d", &M->tu, &N->tu);
	CreateSMatrix(M);
	CreateSMatrix(N);
	AddSMatrix(M, N);
	printSMatrix(M);
	return 0;
}

 

title

求广义表深度(严5.30)

time_limit

3000MS

memory_limit

10000KB

description

试按表头、表尾的分析方法编写求广义表的深度的递归程序。

input

输入一串以‘(’开始,以‘(’结束的字符串,并且输入的左右括号必须匹配,如:(),(())……

output

分别输出按表头、表尾分析方法求广义表深度的结果,每个结果占一行。

sample_input

((a,b,(c,(d,e),f)),g)

sample_output

4

4

#include<iostream>  
#include<string>  
#include<cstdlib>  
using namespace std;

typedef enum { ATOM, LIST } ElemTag;
typedef char AtomType;
typedef struct GLNode//GLNode是一个类型名  
{
	ElemTag tag;//标志域  
	union
	{
		AtomType atom;
		struct { GLNode *hp, *tp; }ptr;
		//ptr是列表,hp,tp分别指向该列表的表头和表尾  
	};
	GLNode()
	{
		ptr.hp = ptr.tp = NULL;
	}
}*List;//List是指向GLNode类型变量的指针类型  

class GLists
{
public:
	void GetGList(List&);//得到广义表  
	void CopyGList(List&, List&);//复制广义表  
	void ListTraverse(List);
	int GListDepth(List&);//求广义表深度  
private:
	void CreatGList(List&, string&);//递归建立广义表  
	void sever(string&, string&);//存储广义表的字符串处理  
};

void GLists::GetGList(List& l)
{
	//cout<<"Please Input The Lists :"<<endl<<endl;  
	string str;
	cin >> str;
	CreatGList(l, str);
}

void GLists::CreatGList(List& l, string& s)//根据给定字符串s,从l递归创建广义表  
{
	List p, q;//广义表节点类型变量  
	string sub, hsub;//两个字符串  
	if (s == "()")//空表  
		l = NULL;//l置空  
	else//非空表  
	{
		l = new GLNode;//建立节点  
		if (s.size() == 1)//原子类型  
		{
			l->tag = ATOM;//标志域  
			l->atom = s[0];//原子  
		}//if  
		else//列表类型  
		{
			l->tag = LIST;//标志域  
			p = l;
			sub = s.substr(1, s.size() - 2);//脱去括号  
			do//根据得到的列表字符串建立新的广义表  
			{
				sever(sub, hsub);//得到列表中“最小单位”hsub,然后把sub置成去掉最小单位的剩余字符串  
				CreatGList(p->ptr.hp, hsub);//递归建立广义表  
				q = p;//记录p  
				if (!sub.empty())//为下一个节点提前开辟节点空间  
				{
					p = new GLNode;
					p->tag = LIST;//更改标志域  
					q->ptr.tp = p;//连接节点  
				}
			} while (!sub.empty());
		}
	}//else  
}

void GLists::CopyGList(List& t, List& l)//复制广义表l->t  
{
	if (!l) t = NULL;//l是空表  
	else
	{
		t = new GLNode;//开辟节点  
		t->tag = l->tag;//标志域  
		if (l->tag == ATOM)//是原子节点  
			t->atom = l->atom;//复制原子  
		else//列表  
		{
			CopyGList(t->ptr.hp, l->ptr.hp);//递归复制表头  
			CopyGList(t->ptr.tp, l->ptr.tp);//递归复制表尾  
		}
	}
}

int GLists::GListDepth(List& l)//求广义表深度  
{
	int max = 0, dep;
	List p = l;
	if (l == NULL) return 1;//空表深度为1  
	if (l->tag == ATOM) return 0;//原子深度为零  
								 //非空列表情况  
	for (; p; p = p->ptr.tp)//遍历列表  
	{
		dep = GListDepth(p->ptr.hp);//递归求深度  
		if (dep>max)//更新max  
			max = dep;
	}
	return max + 1;//返回深度  
}

void GLists::sever(string &str, string &hstr)//广义表字符串处理  
{//将非空字符串分割成两部分hstr为第一个','之前的部分,str为之后的部分  
	int n = str.size(), i = 0, k = 0;
	do
	{
		if (str[i] == '(') k++;
		if (str[i] == ')') k--;
		i++;
	} while (i<n && (str[i] != ',' || k != 0));
	if (i<n)
	{
		hstr = str.substr(0, i);
		str = str.substr(i + 1, n - i - 1);
	}
	else
	{
		hstr = str;
		str.erase(str.begin(), str.end());
	}
}

void GLists::ListTraverse(List L)//广义表遍历  
{
	if (L->tag == ATOM)
	{
		cout << L->atom << ",";
	}
	else
	{
		cout << "(";
		while (L != NULL)
		{
			ListTraverse(L->ptr.hp);
			L = L->ptr.tp;
		}
		cout << ")";
	}
}

int main()
{
	GLists gl;
	List l;
	gl.GetGList(l);

	cout << gl.GListDepth(l) << endl;
	cout << gl.GListDepth(l) << endl;

	//system("pause");  
	return 0;
}

title

建立二叉树的二叉链表存储结构(严6.70)

time_limit

3000MS

memory_limit

10000KB

description

如果用大写字母标识二叉树结点,则一颗二叉树可以用符合下面语法图的字符序列表示。试编写递归程序,由这种形式的字符序列,建立相应的二叉树的二叉链表存储结构(附图见《严蔚敏:数据结构题集(C语言版)》第45页6.70)。

input

输入如图所示的字符序列。

output

建立相应二叉树的二成叉链表存储结构,并先序遍历输出。

sample_input

A(B(#,D),C(E(#,F),#))

sample_output

AB#DCE#F#

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
using namespace std;
typedef char Elemtype;
typedef struct node {
	Elemtype value;
	struct node *lchild, *rchild;
}BitNode, *BiTree;
/*void process(char *s, char *s1)
{
	int len, i, j;
	len = strlen(s);
	for (i = 0, j = 0; i<len; i++) {
		if (s[i] == ',' || s[i] == '(')continue;
		else s1[j++] = s[i];
	}
	s1[j] = '\0';
}*/
void createBitree(BiTree &T)
{
	char c;
	cin >> c;
	if (c == '#') {
		T = (BiTree)malloc(sizeof(BitNode));
		T->lchild = T->rchild = NULL;
		T->value = c;
	}
	else {
		while (c == ',' || c == ')')cin >> c;
		T = (BiTree)malloc(sizeof(BitNode));
		T->value = c;
		T->lchild = T->rchild = NULL;
		cin >> c;
		if (c == '(') {
			createBitree(T->lchild);
			createBitree(T->rchild);
		}
	}
}
void preordertraverse(BiTree T)
{
	if (T) {
		printf("%c", T->value);
		preordertraverse(T->lchild);
		preordertraverse(T->rchild);
	}

}
int main()
{
	BiTree T=NULL;
	createBitree(T);
	preordertraverse(T);
	return 0;
}

 

title

计算二叉树叶子结点数目(耿6.14)

time_limit

3000MS

memory_limit

10000KB

description

二叉树按照二叉链表方式存储,编写程序,计算二叉树中叶子结点的数目。

input

按先序输入二叉树各结点,其中#表示取消建立子树结点。

output

输出二叉树中叶子节点的数目。

sample_input

ABD##EH###CF#I##G##

sample_output

4

#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
int cnt = 0;

typedef struct node {
	char data;
	struct node *lchild, *rchild;
}BiTNode,*BiTree;

void creatBiTree(BiTree &T)
{
	char c;
	cin >> c;
	if (c == '#')T = NULL;
	else {
		T = (BiTree)malloc(sizeof(BiTNode));
		T->data = c;
		creatBiTree(T->lchild);
		creatBiTree(T->rchild);
	}
}

void Traverse(BiTree T)
{
	if (T) {
		if (T->lchild == NULL && T->rchild == NULL)cnt++;
		Traverse(T->lchild);
		Traverse(T->rchild);
	}
}

int main()
{
	BiTree T=NULL;
	creatBiTree(T);
	Traverse(T);
	cout << cnt << endl;
	return 0;
}

 

title

输出以二叉树表示的算术表达式(严6.51)

time_limit

3000MS

memory_limit

10000KB

description

编写程序,输出以二叉树表示的算术表达式,若该表达式中含有括号,则在输出时应添上。

input

按先序输入一行字符,其中#表示取消建立子树结点,即所有叶子节点均为#。

output

输出该二叉树所表示的算术表达式(若表达式中含有括号,则在输出时应添上)。

sample_input

*+a(###b#)##c##

sample_output

(a+b)*c

#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;

typedef struct node {
	char data;
	struct node *lchild, *rchild;
}BitNode, *BiTree;

void createBitree(BiTree &T)
{
	char c;
	cin >> c;
	if (c != '#') {
		T = (BiTree)malloc(sizeof(BitNode));
		T->data = c;
		T->lchild = T->rchild = NULL;
		createBitree(T->lchild);
		createBitree(T->rchild);
	}
}

void inorderTraverse(BiTree T)
{
	if (T) {
		inorderTraverse(T->lchild);
		cout << T->data;
		inorderTraverse(T->rchild);
	}
}

int main()
{
	BiTree T = NULL;
	createBitree(T);
	inorderTraverse(T);
	return 0;
}

title

建立二叉树的二叉链表(严6.65)

time_limit

3000MS

memory_limit

10000KB

description

已知一棵二叉树的前序序列和中序序列分别存于两个一维数组中,试编写算法建立该二叉树的二叉链表。

input

分两行分别输入一棵二叉树的前序序列和中序序列。

output

输出该二叉树的后序序列。

sample_input

ABDFGCEH

BFDGACEH

sample_output

FGDBHECA

#include <iostream>
#include <stdio.h>  
#include <stdlib.h>  
#include <malloc.h>  

using namespace std;
typedef char ElementType;

typedef struct node
{
	ElementType data;
	struct node * leftChild;
	struct node * rightChild;
}BTNode;

//pre:存放先序序列  in:存放中序序列  
BTNode *createBT(char *pre, char *in, int n)
{
	BTNode *b;
	char *p;
	int k;
	if (n <= 0)
		return NULL;
	b = (BTNode *)malloc(sizeof(BTNode));
	b->data = *pre;
	int j = 0;
	for (p = in; p<in + n; p++)
	{
		if (*p == *pre)
			break;
	}
	k = p - in;           //确定根节点在中序序列(in)中的位置 编号为0,1,2,...,n-1 (类似于数组中的下标号,不是逻辑序号)  
	b->leftChild = createBT(pre + 1, in, k);   //递归构造左子数  
	b->rightChild = createBT(pre + 1 + k, p + 1, n - k - 1);  //递归构造右子树  
	return b;
}

void showBTInOrder(BTNode *b)
{
	if (b != NULL)
	{
		showBTInOrder(b->leftChild);
		showBTInOrder(b->rightChild);
		printf("%c", b->data);

	}
}

int main()
{
	BTNode *b = NULL;
	char pre[50];
	char in[50];
	cin >> pre;
	cin >> in;
	b = createBT(pre, in, 7);
	showBTInOrder(b);
	printf("\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41858784/article/details/82181047
今日推荐