数据结构实验(部分)

线性表

  1. 问题描述:设顺序表A中的数据元素递增有序,试写一程序,将x插入到顺序表的适当位置上,使该表仍然有序。
  2. 输入样例:

1 2 3 5 6 7 8 9 10 11 12 -1

4

输出样例:

1 2 3 4 5 6 7 8 9 10 11 12

  1. 存储结构:

线性表的顺序存储结构,P22。

  1. 算法基本思想:

将递增有序序列输入,构造线性表。

插入x时,从后往前遍历并且依次移动元素位置,最后将x插入到合适的位置。

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

# define LIST_INIT_SIZE 10
# define LISTINCREMENT 5
# define ElemType int
# define OK 1

//顺序结构存储线性表的定义
typedef struct {
	ElemType* elem;
	int length;         //当前长度
	int listsize;       //存储容量
}SqList;

void ListPrint(SqList& L);
bool InitList_Sq(SqList& L)
{
	//SqList的初始化
	L.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if (!L.elem)exit(0);
	L.length = 0;
	L.listsize = LIST_INIT_SIZE;
	int i = 0;
	for (i ; i < L.listsize; i++)*(L.elem + i) = 0;

	//构建原递增有序线性表
	ElemType* q = L.elem;
	while(scanf("%d", q))
	{
		if (*q == -1)
		{
			*q = 0;
			break;
		}
		
		q++;
		L.length++;
		if (L.length >= L.listsize)
		{
			ElemType* newbase = (ElemType*)realloc(L.elem,(L.listsize + LISTINCREMENT) * sizeof(ElemType));
			if (!newbase)exit(0);
			L.elem = newbase;
			L.listsize += LISTINCREMENT;
			q = L.elem + L.length;

			int i;
			for (i=L.length ; i < L.listsize; i++)*(L.elem + i) = 0;
		}
	}

	return OK;
}

//向原递增有序线性表在合适的位置上插入元素e
//从后往前遍历并且依次移动元素位置
void ListInsert_Sq(SqList& L, ElemType e)
{
	ElemType* q = L.elem+L.length-1;
	while (*q > e)
	{
		*(q+1) = *q;
		q--;
	}
	*(q + 1) = e;
	L.length++;
}

void ListPrint(SqList& L)
{
	for (ElemType* q = L.elem; *q; q++)
	{
		printf("%d ", *q);
	}
	puts("");
}

int main(void)
{
	SqList l;
	InitList_Sq(l);

	int e;
	scanf("%d", &e);
	
	ListInsert_Sq(l, e);

	ListPrint(l);

	return 0;
}
  1. 问题描述:用单链表ha 存储多项式A(x )=a0+a1x1+a2x2+…+anxn(其中aI为非零系数),用单链表hb 存储多项式B(x )=b0+b1x1+b2x2+…+bmxm(其中bj为非零系数),要求计算C(x )= A(x )+B(x ),结果存到单链表hc中。试写出程序。
  2. 输入样例:

3 1 1 2 2 4 3

4 5 2 1 3 1 4 2 5

输出样例:

(1 ,1 )

(7 ,2 )

(5 ,3 )

(1 ,4 )

(2 ,5 )

  1. 存储结构:

线性表的链式存储结构,P28。

  1. 算法基本思想:

合并链表。

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

typedef struct LNode {
	int coef;      //系数
	int index;     //指数
	struct LNode* next;
}LNode, * LinkList;

//构造线性链表
void CreateList_L(LinkList& L, int n)
{
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;

	LinkList m = L;

	for (int i = 0; i < n; i++)
	{
		LinkList p = (LinkList)malloc(sizeof(LNode));
		scanf("%d%d", &p->coef, &p->index);
		p->next = m->next;
		m->next = p;
		m = m->next;
	}
}

//多项式相加,顺便释放AB
void ADD(LinkList& A, LinkList& B, LinkList& C)
{
	LinkList a = A;
	LinkList b = B;
	LinkList c = C;

	while (a && b)
	{
		if (a->index <= b->index)   //合并a
		{
			LinkList p = (LinkList)malloc(sizeof(LNode));

			p->coef = a->coef;
			p->index = a->index;

			p->next = c->next;
			c->next = p;
			c = c->next;

			LinkList tmp1 = a, tmp2 = b;
			if (a->index == b->index)
			{
				p->coef += b->coef;
				a = a->next;
				free(tmp1);

				b = b->next;
				free(tmp2);
			}
			else
			{
				a = a->next;
				free(tmp1);
			}
		}
		else                // a->index > b->index; 合并b
		{
			LinkList p = (LinkList)malloc(sizeof(LNode));

			p->coef = b->coef;
			p->index = b->index;

			p->next = c->next;
			c->next = p;
			c = c->next;

			LinkList tmp = b;
			b = b->next;
			free(tmp);
		}
	}

	if (a != NULL)c->next = a;
	if (b != NULL)c->next = b;
}

void Print(LinkList& L)
{
	LinkList p;
	for (LinkList p = L->next; p; p = p->next)
	{
		printf("(%d ,%d )\n", p->coef, p->index);
	}
}

int main(void)
{
	LinkList ha, hb, hc;
	CreateList_L(hc, 0);

	int cnta;
	scanf("%d", &cnta);
	CreateList_L(ha, cnta);

	int cntb;
	scanf("%d", &cntb);
	CreateList_L(hb, cntb);

	LinkList t = ha;
	ha = ha->next;
	free(t);

	t = hb;
	hb = hb->next;
	free(t);

	ADD(ha, hb, hc);

	Print(hc);

	return 0;
}

  1. 问题描述:

设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人重新开始报数,数到m的人又出列,如此重复,直到所有的人全部出列为止。Josephus问题是:对于任意给定的n,m,s,求出按出列次序得到的n个人员的顺序表。

  1. 输入样例:

8(n)

3(s)

4(m)

输出样例:

6 2 7 4 3 5 1 8

  1. 存储结构:

无头结点的循环链表。

  1. 算法基本思想:

模拟游戏过程。

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

typedef struct Node{
	int no;
	struct Node* next;
}Node;

//初始化循环链表
Node* InitLink(int n)
{
	Node* tmp = (Node*)malloc(sizeof(Node));     //第一个节点单独创建
	tmp->no = 1;
	Node* head, * tail;
	head = tail = tmp;
	tail->next = NULL;

	int i;
	for (i = 2; i <=n; i++)                 
	{
		Node* t = (Node*)malloc(sizeof(Node));
		t->no = i;

		t->next = tail->next;
		tail->next = t;
		tail = tail->next;
	}
	tail->next = head;       //循环链表最后一个节点指针域指回第一个节点

	return head;
}

//模拟游戏
void RunGame(int s, int m, Node* head,int sum)
{
	Node* fa = head;       //方便删除操作
	head = head->next;

	int i;
	for (i = 1; i < s-1; i++)
	{
		head = head->next;
		fa = fa->next;
	}

	while (sum)
	{
		int j;
		for (j = 1; j < m; j++)
		{
			head = head->next;
			fa = fa->next;
		}

		printf("%d ", head->no);
		
		if (sum > 1)
		{
			fa->next = head->next;
			free(head);
			head = fa->next;
		}
		else
		{
			free(head);
		}

		sum--;
		
	}
}

int main(void)
{
	int n, m, s;
	scanf("%d%d%d", &n, &s, &m);

	Node* head;
	head=InitLink(n);

	RunGame(s, m, head, n);

	return 0;
}

  1. 问题描述:

编写递归算法,计算二叉树中叶子结点的数目。

  1. 输入样例:

ABD..EH...CF.I..G..(前序序列输入)

输出样例:

4

  1. 存储结构:

二叉链表。

  1. 算法基本思想:

按前序序列建树,求叶子节点。

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

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

BiTree InitBiTree(BiTree fa,int flag)
{
	char root_value;
	scanf("%c", &root_value);

	if (root_value == '.')
	{
		if (flag == 1)
		{
			fa->lchild = NULL;
			return NULL;
		}
		else if (flag == 2)
		{
			fa->rchild = NULL;
			return NULL;
		}
		else return NULL;
	}
	else
	{
		BiTree root = (BiTree)malloc(sizeof(BiTNode));
		root->data = root_value;
		
		if (flag == 1)
		{
			fa->lchild = root;
		}
		else if(flag == 2)
		{
			fa->rchild = root;
		}

		InitBiTree(root, 1);
		InitBiTree(root, 2);

		return root;
	}

}

void LeafNode(BiTree root,int& sum)
{
	if (root->lchild == NULL && root->rchild == NULL)
	{
		sum++;
		return;
	}

	if (root->lchild)LeafNode(root->lchild, sum);
	if (root->rchild)LeafNode(root->rchild, sum);
}

int main(void)
{
	BiTree root=InitBiTree(NULL, 0);

	int sum = 0;
	LeafNode(root, sum);
	printf("%d\n", sum);

	return 0;
}

  1. 问题描述:

编写递归算法,在二叉树中求位于先序序列中第K个位置的结点。

  1. 输入样例:

ABD..EH...CF.I..G..(前序序列输入)

5`

输出样例:

H

  1. 存储结构:

二叉链表。

  1. 算法基本思想:

按前序序列建树,按前序遍历进行搜索,搜索同时计数,直到第k个输出。

(我愿称之最无用的代码)

# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
# include <stdlib.h>

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

BiTree InitBiTree(BiTree fa, int flag)
{
	char root_value;
	scanf("%c", &root_value);

	if (root_value == '.')
	{
		if (flag == 1)
		{
			fa->lchild = NULL;
			return NULL;
		}
		else if (flag == 2)
		{
			fa->rchild = NULL;
			return NULL;
		}
		else return NULL;
	}
	else
	{
		BiTree root = (BiTree)malloc(sizeof(BiTNode));
		root->data = root_value;

		if (flag == 1)
		{
			fa->lchild = root;
		}
		else if (flag == 2)
		{
			fa->rchild = root;
		}

		InitBiTree(root, 1);
		InitBiTree(root, 2);

		return root;
	}

}

BiTree Print(BiTree root, int k, int &cnt)
{
	if (root)
	{
		cnt++;
		if (cnt == k)
		{
			printf("%c\n", root->data);
		}
	}
	else
	{
		return NULL;
	}

	Print(root->lchild, k, cnt);
	Print(root->rchild, k, cnt);
}

int main(void)
{
	BiTree root = InitBiTree(NULL, 0);

	int k, cnt = 0;
	scanf("%d", &k);

	Print(root, k, cnt);

	return 0;
}

  1. 问题描述:

将上述例题用非递归程序实现。

  1. 输入样例:

同上。

输出样例:

同上。

  1. 存储结构:

二叉链表。

  1. 算法基本思想:

实习题1:采用层序遍历来计算叶子节点的数目。

# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
# include <stdlib.h>

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

BiTree InitBiTree(BiTree fa, int flag)
{
	char root_value;
	scanf("%c", &root_value);

	if (root_value == '.')
	{
		if (flag == 1)
		{
			fa->lchild = NULL;
			return NULL;
		}
		else if (flag == 2)
		{
			fa->rchild = NULL;
			return NULL;
		}
		else return NULL;
	}
	else
	{
		BiTree root = (BiTree)malloc(sizeof(BiTNode));
		root->data = root_value;

		if (flag == 1)
		{
			fa->lchild = root;
		}
		else if (flag == 2)
		{
			fa->rchild = root;
		}

		InitBiTree(root, 1);
		InitBiTree(root, 2);

		return root;
	}

}

bool LeafNode(BiTree root, int& sum)
{
	if (root == NULL)return false;

	BiTree q[50];
	int head = 0, tail = 0;
	q[tail++] = root;

	while (head != tail)
	{
		if (q[head]->lchild == NULL && q[head]->rchild == NULL)
		{
			sum++;
		}

		if(q[head]->lchild)
		{
			q[tail++] = q[head]->lchild;
		}

		if (q[head]->rchild)
		{
			q[tail++] = q[head]->rchild;
		}

		head++;
	}
	return true;
}

int main(void)
{
	BiTree root = InitBiTree(NULL, 0);

	int sum = 0;
	LeafNode(root, sum);
	printf("%d\n", sum);

	return 0;
}

实习题2:采用栈来实现前序遍历的迭代写法。

# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
# include <stdlib.h>

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

BiTree InitBiTree(BiTree fa, int flag)
{
	char root_value;
	scanf("%c", &root_value);

	if (root_value == '.')
	{
		if (flag == 1)
		{
			fa->lchild = NULL;
			return NULL;
		}
		else if (flag == 2)
		{
			fa->rchild = NULL;
			return NULL;
		}
		else return NULL;
	}
	else
	{
		BiTree root = (BiTree)malloc(sizeof(BiTNode));
		root->data = root_value;

		if (flag == 1)
		{
			fa->lchild = root;
		}
		else if (flag == 2)
		{
			fa->rchild = root;
		}

		InitBiTree(root, 1);
		InitBiTree(root, 2);

		return root;
	}

}

// 前序遍历的迭代写法
bool Print(BiTree root, int k, int& cnt)
{
	if (root == NULL)return false;

	BiTree q[50];
	int tail = 0;
	q[tail++] = root;

	while (tail != 0)
	{
		if (++cnt == k)
		{
			printf("%c\n", q[tail - 1]->data);
		}

		BiTree tmp = q[--tail];

		if (tmp->rchild)q[tail++] = tmp->rchild;
		if (tmp->lchild)q[tail++] = tmp->lchild;
	}

	return true;
}

int main(void)
{
	BiTree root = InitBiTree(NULL, 0);

	int k, cnt = 0;
	scanf("%d", &k);

	Print(root, k, cnt);

	return 0;
}

  1. 问题描述:

采用邻接表存储结构,编写一个求无向图的连通分量个数的算法。

  1. 输入样例:

7 6

1 2

2 3

4 5

5 6

5 7

6 7

输出样例:

2

  1. 存储结构:

邻接表。

  1. 算法基本思想:

广搜确定连通块数量。

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

# define MAX_VERTEX_NUM 20

//弧的相关信息
typedef struct ArcNode {
	int adjvex;                //弧所指向的节点的编号
	struct ArcNode* nextarc;   //下一条弧的指针
}ArcNode;

//顶点的信息
typedef struct VNode {
	int data;           //节点信息
	ArcNode* firstarc;  //指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];

//建图
typedef struct {
	AdjList ver;         //图中节点列表 
	int vernum, arcnum;  //点数,边数
}ALGraph;

void InitGraph(ALGraph& g)
{
	scanf("%d%d", &g.vernum, &g.arcnum);
	for (int i = 1; i <= g.vernum; i++)
	{
		g.ver[i].firstarc = NULL;
	}
	
	int i;
	for (i = 0; i < g.arcnum; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);

		ArcNode* arc1 = (ArcNode*)malloc(sizeof(ArcNode));
		arc1->adjvex = b;
		arc1->nextarc = NULL;

		if (!g.ver[a].firstarc)
		{
			g.ver[a].firstarc = arc1;
		}
		else
		{
			ArcNode* tmp = g.ver[a].firstarc;
			while (tmp->nextarc)tmp = tmp->nextarc;
			tmp->nextarc = arc1;
		}

		ArcNode* arc2 = (ArcNode*)malloc(sizeof(ArcNode));
		arc2->adjvex = a;
		arc2->nextarc = NULL;

		if (!g.ver[b].firstarc)
		{
			g.ver[b].firstarc = arc2;
		}
		else
		{
			ArcNode* tmp2 = g.ver[b].firstarc;
			while (tmp2->nextarc)tmp2 = tmp2->nextarc;
			tmp2->nextarc = arc2;
		}
	}
}

int visited[MAX_VERTEX_NUM] = { 0 };

void Rearch(ALGraph g,int start)
{
	visited[start] = 1;

	ArcNode* op;
	for (op = g.ver[start].firstarc; op; op = op->nextarc)
	{
		if (visited[op->adjvex] == 1)continue;
		Rearch(g, op->adjvex);
	}
}

void CountConnectionBlock(int& sum, ALGraph g)
{
	for (int i = 1; i <= g.vernum; i++)
	{
		if (visited[i] == 0)
		{
			Rearch(g, i);
			sum++;
		}
	}
}

int main(void)
{
	ALGraph g;

	InitGraph(g);

	int sum = 0;
	CountConnectionBlock(sum, g);
	printf("%d\n", sum);

	return 0;
}

  1. 问题描述:

试基于图的深度优先搜索策略编写一程序,判别以邻接表方式存储的有向图中是否存在有顶点Vi到Vj顶点的路径(i≠j)。

  1. 输入样例:

7 6

1 2

2 3

4 5

5 6

5 7

6 7

2 5

输出样例:

No

  1. 存储结构:

邻接表。

  1. 算法基本思想:

深度优先搜索。

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

# define MAX_VERTEX_NUM 20

//弧的相关信息
typedef struct ArcNode {
	int adjvex;                //弧所指向的节点的编号
	struct ArcNode* nextarc;   //下一条弧的指针
}ArcNode;

//顶点的信息
typedef struct VNode {
	int data;           //节点信息
	ArcNode* firstarc;  //指向第一条依附该顶点的弧的指针
}VNode, AdjList[MAX_VERTEX_NUM];

//建图
typedef struct {
	AdjList ver;         //图中节点列表 
	int vernum, arcnum;  //点数,边数
}ALGraph;

void InitGraph(ALGraph& g)
{
	scanf("%d%d", &g.vernum, &g.arcnum);
	for (int i = 1; i <= g.vernum; i++)
	{
		g.ver[i].firstarc = NULL;
		g.ver[i].data = i;
	}

	int i;
	for (i = 0; i < g.arcnum; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);

		ArcNode* arc1 = (ArcNode*)malloc(sizeof(ArcNode));
		arc1->adjvex = b;
		arc1->nextarc = NULL;

		if (!g.ver[a].firstarc)
		{
			g.ver[a].firstarc = arc1;
		}
		else
		{
			ArcNode* tmp = g.ver[a].firstarc;
			while (tmp->nextarc)tmp = tmp->nextarc;
			tmp->nextarc = arc1;
		}
	}
}

bool st[MAX_VERTEX_NUM] = { 0 };

bool Judge(int end, ALGraph& g,int cur)
{
	if (cur == end)return true;
	st[cur] = 1;

	ArcNode* op;
	for (op = g.ver[cur].firstarc; op; op = op->nextarc)
	{
		if (!st[op->adjvex])
		{
			if (Judge(end, g, op->adjvex))return true;
		}
	}
}


int main(void)
{
	ALGraph g;

	InitGraph(g);

	int start, end;
	scanf("%d%d", &start, &end);

	if (Judge(end, g, start))puts("Yes");
	else puts("No");

	return 0;
}

  1. 问题描述:

在上述例题中,如改用邻接表的方式存储图,试编一程序实现上述算法。

顶点表nodelist的每个元素包含四个字段:

info

mark

pre

out

其中mark为布尔类型,用来标记顶点是否被访问过。开始时,所有元素的mark字段为false,每访问过一个顶点,则mark字段置为true。info为顶点值,pre为访问路径上该顶点的前驱顶点的序号,out指向该顶点的出边表。

  1. 输入样例:

同上。

输出样例:

同上。

  1. 存储结构:

二叉链表。

  1. 算法基本思想:

已采用邻接表方式进行存储,本题只需重新定义顶点,并维护算法过程即可。

(我愿称之最好改的代码)

# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
# include <stdlib.h>

# define MAX_VERTEX_NUM 20

//弧的相关信息
typedef struct ArcNode {
	int adjvex;                //弧所指向的节点的编号
	struct ArcNode* nextarc;   //下一条弧的指针
}ArcNode;

//顶点的信息
typedef struct VNode {
	bool mark;          //标记顶点是否被访问
	int pre;            //访问路径上该顶点的前驱顶点的序号
	int info;           //为顶点值
	int data;           //节点信息
	ArcNode* firstarc;  //指向第一条依附该顶点的弧的指针,即题中要求的out指针
}VNode, AdjList[MAX_VERTEX_NUM];

//建图
typedef struct {
	AdjList ver;         //图中节点列表 
	int vernum, arcnum;  //点数,边数
}ALGraph;

void InitGraph(ALGraph& g)
{
	scanf("%d%d", &g.vernum, &g.arcnum);
	for (int i = 1; i <= g.vernum; i++)
	{
		g.ver[i].firstarc = NULL;
		g.ver[i].info = i;
		g.ver[i].mark = false;
	}

	int i;
	for (i = 0; i < g.arcnum; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);

		ArcNode* arc1 = (ArcNode*)malloc(sizeof(ArcNode));
		arc1->adjvex = b;
		arc1->nextarc = NULL;

		if (!g.ver[a].firstarc)
		{
			g.ver[a].firstarc = arc1;
		}
		else
		{
			ArcNode* tmp = g.ver[a].firstarc;
			while (tmp->nextarc)tmp = tmp->nextarc;
			tmp->nextarc = arc1;
		}

		ArcNode* arc2 = (ArcNode*)malloc(sizeof(ArcNode));
		arc2->adjvex = a;
		arc2->nextarc = NULL;

		if (!g.ver[b].firstarc)
		{
			g.ver[b].firstarc = arc2;
		}
		else
		{
			ArcNode* tmp2 = g.ver[b].firstarc;
			while (tmp2->nextarc)tmp2 = tmp2->nextarc;
			tmp2->nextarc = arc2;
		}
	}
}

void Rearch(ALGraph& g, int start)
{
	g.ver[start].mark = true;

	ArcNode* op;
	for (op = g.ver[start].firstarc; op; op = op->nextarc)
	{
		if (g.ver[op->adjvex].mark == true)continue;

		g.ver[op->adjvex].pre = start;
		Rearch(g, op->adjvex);
	}
}

void CountConnectionBlock(int& sum, ALGraph g)
{
	for (int i = 1; i <= g.vernum; i++)
	{
		if (g.ver[i].mark == false)
		{
			Rearch(g, i);
			sum++;

			//for (int j = 1; j <= g.vernum; j++)
			//{
			//	printf("%d %d \n", j, g.ver[j].mark);
			//}
		}
	}
}

int main(void)
{
	ALGraph g;

	InitGraph(g);

	int sum = 0;
	CountConnectionBlock(sum, g);
	printf("%d\n", sum);

	return 0;
}

# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
# include <stdlib.h>

# define MAX_VERTEX_NUM 20

//弧的相关信息
typedef struct ArcNode {
	int adjvex;                //弧所指向的节点的编号
	struct ArcNode* nextarc;   //下一条弧的指针
}ArcNode;

//顶点的信息
typedef struct VNode {
	bool mark;          //标记顶点是否被访问
	int pre;            //访问路径上该顶点的前驱顶点的序号
	int info;           //为顶点值
	int data;           //节点信息
	ArcNode* firstarc;  //指向第一条依附该顶点的弧的指针,即题中要求的out指针
}VNode, AdjList[MAX_VERTEX_NUM];

//建图
typedef struct {
	AdjList ver;         //图中节点列表 
	int vernum, arcnum;  //点数,边数
}ALGraph;

void InitGraph(ALGraph& g)
{
	scanf("%d%d", &g.vernum, &g.arcnum);
	for (int i = 1; i <= g.vernum; i++)
	{
		g.ver[i].firstarc = NULL;
		g.ver[i].info = i;
		g.ver[i].mark = false;
	}

	int i;
	for (i = 0; i < g.arcnum; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);

		ArcNode* arc1 = (ArcNode*)malloc(sizeof(ArcNode));
		arc1->adjvex = b;
		arc1->nextarc = NULL;

		if (!g.ver[a].firstarc)
		{
			g.ver[a].firstarc = arc1;
		}
		else
		{
			ArcNode* tmp = g.ver[a].firstarc;
			while (tmp->nextarc)tmp = tmp->nextarc;
			tmp->nextarc = arc1;
		}
	}
}

bool Judge(int end, ALGraph& g, int cur)
{
	if (cur == end)return true;
	g.ver[cur].mark = true;

	ArcNode* op;
	for (op = g.ver[cur].firstarc; op; op = op->nextarc)
	{
		if (g.ver[cur].mark = false)
		{
			g.ver[op->adjvex].pre = cur;
			if (Judge(end, g, op->adjvex))return true;
		}
	}
}


int main(void)
{
	ALGraph g;

	InitGraph(g);

	int start, end;
	scanf("%d%d", &start, &end);

	if (Judge(end, g, start))puts("Yes");
	else puts("No");

	return 0;
}

查找

  1. 问题描述:

编写程序实现下面运算:在二叉排序树中查找关键字为key的记录。

  1. 输入样例:

5 2 1 0 0 4 3 0 0 0 8 6 0 7 0 0 9 0 0 (二叉排序树前序序列输入)

7

输出样例:

Yes

  1. 存储结构:

二叉树的二叉链表存储表示。

  1. 算法基本思想:

递归查找。

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

# define KeyType int

typedef struct {

}Info;

typedef struct BiTNode {
	KeyType key;
	Info info;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;

BiTree InitBiTree(BiTree fa, int flag)
{
	int key_value;
	scanf("%d", &key_value);

	if (key_value == 0)
	{
		if (flag == 1)
		{
			fa->lchild = NULL;
			return NULL;
		}
		else if (flag == 2)
		{
			fa->rchild = NULL;
			return NULL;
		}
		else return NULL;
	}
	else
	{
		BiTree root = (BiTree)malloc(sizeof(BiTNode));
		root->key = key_value;

		if (flag == 1)
		{
			fa->lchild = root;
		}
		else if (flag == 2)
		{
			fa->rchild = root;
		}

		InitBiTree(root, 1);
		InitBiTree(root, 2);

		return root;
	}

}

BiTree Search(BiTree root, int key)
{
	if (!root || root->key == key)return root;
	else if (root->key > key)return Search(root->lchild, key);
	else return Search(root->rchild, key);
}



int main(void)
{
	BiTree root = InitBiTree(NULL, 0);

	int key_search;
	scanf("%d", &key_search);
	if (Search(root, key_search))puts("Yes");
	else puts("No");

	return 0;
}

  1. 问题描述:

试将折半查找的算法改写成递归算法。

  1. 输入样例:

8

14 18 20 25 36 90 100 301

25

输出样例:

4

  1. 存储结构:

typedef struct{
  KeyType key;

  …..

}

P215

  1. 算法基本思想:

折半查找属于有序表的查找。

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

# define KeyType int
# define MAX_ELEM_NUM 20

typedef struct {

}Info;

typedef struct {
	KeyType key;
	Info info;
}ElemType, ElemList[MAX_ELEM_NUM];

int Search_Bin(KeyType aim, ElemList& q, int left, int right)
{
	int mid = (left + right) / 2;
	if (q[mid].key == aim)return mid;
	else if (q[mid].key < aim)return Search_Bin(aim, q, mid, right);
	else return Search_Bin(aim, q, left, mid);
}

int main(void)
{
	int sum;
	scanf("%d", &sum);

	ElemList q;

	int i;
	for (i = 1; i <= sum; i++)scanf("%d", &q[i].key);

	int aim;
	scanf("%d", &aim);

	int ans = Search_Bin(aim, q, 1, sum);
	printf("%d\n", ans);

	return 0;
}

内部排序

1

  1. 问题描述:

设计一个用链表表示的直接选择排序算法,并用程序实现。

算法说明:已知待排序初始序列用单链表存贮,头指针head指向第一个结点,从这个待排序列中找出最小结点,插入head之后,用r来指示。r以前为已排序序列,r以后为未排序序列。再从未排序序列中找出最小结点插入r的后面,让r指向这个结点。反复执行这个过程,直到排好序。

  1. 输入样例:

8

8 7 6 5 4 3 2 1

输出样例:

1 2 3 4 5 6 7 8

  1. 存储结构:

链表。

  1. 算法基本思想:

直接选择排序。

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

typedef struct LNode {
	int data;
	struct LNode* next;
}LNode, * LinkList;

LinkList InitLink(int cnt)
{
	LinkList head = (LinkList)malloc(sizeof(LNode));
	head->next = NULL;
	LinkList tail = head;

	int i;
	for (i = 0; i < cnt; i++)
	{
		LinkList tmp = (LinkList)malloc(sizeof(LNode));
		scanf("%d", &tmp->data);

		tmp->next = tail->next;
		tail->next = tmp;
		tail = tail->next;
	}

	return head;
}

void Sort(LinkList head,int cnt)
{
	int i;
	LinkList r = head;
	for (i = 1; i < cnt; i++)
	{
		LinkList quick = r->next, slow = r;
		int minx = 0x3f3f3f3f;

		LinkList op;
		for (op = r->next; op; op = op->next)
		{
			if (op->data < minx)
			{
				minx = op->data;
				while (quick != op)
				{
					quick = quick->next;
					slow = slow->next;
				}
			}
		}

		slow->next = quick->next;
		quick->next = r->next;
		r->next = quick;
		r = r->next;
	}

}

void PrintList(LinkList head)
{
	LinkList op;
	for (op = head->next; op; op = op->next)
	{
		printf("%d ", op->data);
	}
	puts("");
}

int main(void)
{
	int cnt;
	scanf("%d", &cnt);

	LinkList head=InitLink(cnt);

	Sort(head,cnt);

	PrintList(head);

	return 0;
}

  1. 问题描述:

对N个关键字取整数的记录进行整序,以使所有关键字为非负数的记录排在关键字为负数的记录之前,要求使用最少的附加空间,且算法的时间复杂度为O(N)。

  1. 输入样例:

8

-1 1 -2 2 -3 3 -4 4

输出样例:

-1 -4 -2 -3 2 3 1 4

  1. 存储结构:

顺序表。

  1. 算法基本思想:

双指针移动。设L和R指针,将不符合条件的两项交换。

# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
# include <stdlib.h>

# define MAXSIZE 20
# define KeyType int
# define InfoType int

typedef struct RedType{
	KeyType key;
	InfoType otherinfo;
}RedType;

typedef struct SqList {
	RedType r[MAXSIZE + 1];
	int length;
}SqList;

void swap(RedType &a,RedType &b)
{
	RedType c;
	c.key = a.key;
	c.otherinfo = a.otherinfo;

	a.key = b.key;
	a.otherinfo = b.otherinfo;

	b.key = c.key;
	b.otherinfo = c.otherinfo;
}

void sort(SqList &q)
{
	int l = 1, rx = q.length;
	while (l <= rx)
	{
		while (q.r[l].key < 0)
		{
			l++;
		}
		while (q.r[rx].key >= 0)
		{
			rx--;
		}

		if (l <= rx)swap(q.r[l], q.r[rx]);
	}
}

void Print(SqList q)
{
	for (int i = 1; i <= q.length; i++)
	{
		printf("%d ", q.r[i].key);
	}
}

int main(void)
{
	int n;
	scanf("%d", &n);

	SqList q;
	q.length = n;

	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &q.r[i].key);
	}

	sort(q);

	Print(q);

	return 0;

}

开始时间:2022年某天。

结束时间:2023-03-10-21:16。

还债结束,正式回归。

PS:样例很少,bug很多。

顺序存储的线性表 时数 2 性质 验证 内容:1、线性表存放在向量A[arrsize]的前elenum个分量,且递增有序。试计一算法,将x插入到线性表的适当位置上,以保持线性表的有序性。 2、用向量作存储结构,试计一个算法,仅用一个辅助结点,实现将线性表的结点循环右移k位的运算。 3、用向量作存储结构,试计一个算法,仅用一个辅助结点,实现将线性表逆置的运算。 要求:了解线性表的逻辑结构特征,熟练掌握线性表的顺序存储结构的描述方法,及在其上实现各种基本运算的方法。 单链表上的操作 时数 2 性质 验证 内容:1、已知带头结点的动态单链表L的结点是按整数值递增排序的,试写一算法将值为x的结点插入到表L,使L仍然有序。 2、计一算法,逆置带头结点的动态链表L。要求利用原表的结点空间,并要求用尽可能少的时间完成。 3、假有两个按元素递增有序的线性表A和B,均以单链表作存储结构,试编写算法将A表和B表归并成一个按元素值递减有序的线性表C,并要求利用原表的空间存放C。 要求:熟练掌握线性表的单链式链接存储结构及在其上实现线性表的各种基本运算的方法。 循环链表和双链表 时数 2 性质 验证 内容:1、假在长度大于1的单循环链表,既无头结点也无头指针。s为指向某个结点的指针,试编写算法删除结点*s的直接前驱结点。 2、已知由单链表表示的线性表,含有三类字符的数据元素(如:字母、数字和其它字符),计算法构造三个以循环链表示的线性表,使每一个表只含同一类的字符,且利用原表的结点空间作为这三个表的空间。(头结点可以另辟空间) 3、有一双链表,每个结点除有prior、data和next域外,还有一访问频度域freq,在链表被启用前,其值均初始化为零。每当在链表上进行一次LOCATE(L,x)运算,元素值为x的结点freq域的值增1,并使此链表结点保持按freq递减的顺序排列,以便使频繁访问的结点总是靠近表头。计满足上述要求的LOCATE算法。 要求:熟练掌握线性表的循环链式和双链式链接存储结构及在其上实现线性表的各种基本运算的方法。 栈和队列 时数 2 性质 验证 内容:1、链表存放着n个字符,计算法,判断该字符串是否有心对称关系。例如:xyzzyx、xyzyx都算是心对称的字符串。 2、计算法判断一个算术表达式的圆括号是否配对。(提示:对表达式进行扫描,遇‘(’进栈,遇‘)’退掉栈顶的‘(’,表达式被扫描完毕,栈为空) 3、假以带头结点的循环链表表示队列,并只一个指针指向队尾,编写相应的置队空、入队和出队算法。 要求:掌握栈和队列的数据结构的特点;熟练掌握在两种存储结构上实现栈和队列的基本运算;学会利用栈和队列解决一些实际问题。 串运算的实现 时数 2 性质 验证 内容:1、若X和Y是用结点大小为1的单链表表示的串,计算法找出X第一个不在Y出现的字符。 2、计一算法,在顺序串上实现串的比较运算strcmp(S,T)。 3、若S和T是用结点大小为1的单链表存储的两个串,计算法将S首次与T匹配的子串逆置。 要求:熟练掌握串的顺序和链接存储结构的实现方法;熟练掌握在两种存储结构上实现串的各种运算。 树的应用 时数 2 性质 验证 内容:1、以二叉链表作存储结构,计求二叉树高度的算法。 2、一棵n个结点的完全二叉树用向量作存储结构,用非递归算法实现对该二叉树进行前序遍历。 3、以二叉链表作存储结构,编写非递归的前序、序、后序遍历算法。 要求:熟悉二叉树的各种存储结构的特点及适用范围;掌握建立二叉树的存储结构的方法;熟练掌握二叉树的前序、序、后序遍历的递归及非递归算法;灵活运用递归的遍历算法实现二叉树的其它各种运算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值