线性表
- 问题描述:设顺序表A中的数据元素递增有序,试写一程序,将x插入到顺序表的适当位置上,使该表仍然有序。
- 输入样例:
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
- 存储结构:
线性表的顺序存储结构,P22。
- 算法基本思想:
将递增有序序列输入,构造线性表。
插入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;
}
- 问题描述:用单链表ha 存储多项式A(x )=a0+a1x1+a2x2+…+anxn(其中aI为非零系数),用单链表hb 存储多项式B(x )=b0+b1x1+b2x2+…+bmxm(其中bj为非零系数),要求计算C(x )= A(x )+B(x ),结果存到单链表hc中。试写出程序。
- 输入样例:
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 )
- 存储结构:
线性表的链式存储结构,P28。
- 算法基本思想:
合并链表。
# 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;
}
- 问题描述:
设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人重新开始报数,数到m的人又出列,如此重复,直到所有的人全部出列为止。Josephus问题是:对于任意给定的n,m,s,求出按出列次序得到的n个人员的顺序表。
- 输入样例:
8(n)
3(s)
4(m)
输出样例:
6 2 7 4 3 5 1 8
- 存储结构:
无头结点的循环链表。
- 算法基本思想:
模拟游戏过程。
# 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;
}
树
- 问题描述:
编写递归算法,计算二叉树中叶子结点的数目。
- 输入样例:
ABD..EH...CF.I..G..(前序序列输入)
输出样例:
4
- 存储结构:
二叉链表。
- 算法基本思想:
按前序序列建树,求叶子节点。
# 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;
}
- 问题描述:
编写递归算法,在二叉树中求位于先序序列中第K个位置的结点。
- 输入样例:
ABD..EH...CF.I..G..(前序序列输入)
5`
输出样例:
H
- 存储结构:
二叉链表。
- 算法基本思想:
按前序序列建树,按前序遍历进行搜索,搜索同时计数,直到第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:采用层序遍历来计算叶子节点的数目。
# 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;
}
图
- 问题描述:
采用邻接表存储结构,编写一个求无向图的连通分量个数的算法。
- 输入样例:
7 6
1 2
2 3
4 5
5 6
5 7
6 7
输出样例:
2
- 存储结构:
邻接表。
- 算法基本思想:
广搜确定连通块数量。
# 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;
}
- 问题描述:
试基于图的深度优先搜索策略编写一程序,判别以邻接表方式存储的有向图中是否存在有顶点Vi到Vj顶点的路径(i≠j)。
- 输入样例:
7 6
1 2
2 3
4 5
5 6
5 7
6 7
2 5
输出样例:
No
- 存储结构:
邻接表。
- 算法基本思想:
深度优先搜索。
# 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;
}
- 问题描述:
在上述例题中,如改用邻接表的方式存储图,试编一程序实现上述算法。
顶点表nodelist的每个元素包含四个字段:
info | mark | pre | out |
其中mark为布尔类型,用来标记顶点是否被访问过。开始时,所有元素的mark字段为false,每访问过一个顶点,则mark字段置为true。info为顶点值,pre为访问路径上该顶点的前驱顶点的序号,out指向该顶点的出边表。
- 输入样例:
同上。
输出样例:
同上。
- 存储结构:
二叉链表。
- 算法基本思想:
已采用邻接表方式进行存储,本题只需重新定义顶点,并维护算法过程即可。
(我愿称之最好改的代码)
# 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;
}
查找
- 问题描述:
编写程序实现下面运算:在二叉排序树中查找关键字为key的记录。
- 输入样例:
5 2 1 0 0 4 3 0 0 0 8 6 0 7 0 0 9 0 0 (二叉排序树前序序列输入)
7
输出样例:
Yes
- 存储结构:
二叉树的二叉链表存储表示。
- 算法基本思想:
递归查找。
# 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;
}
- 问题描述:
试将折半查找的算法改写成递归算法。
- 输入样例:
8
14 18 20 25 36 90 100 301
25
输出样例:
4
- 存储结构:
typedef struct{
KeyType key;
…..
}
P215
- 算法基本思想:
折半查找属于有序表的查找。
# 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
- 问题描述:
设计一个用链表表示的直接选择排序算法,并用程序实现。
算法说明:已知待排序初始序列用单链表存贮,头指针head指向第一个结点,从这个待排序列中找出最小结点,插入head之后,用r来指示。r以前为已排序序列,r以后为未排序序列。再从未排序序列中找出最小结点插入r的后面,让r指向这个结点。反复执行这个过程,直到排好序。
- 输入样例:
8
8 7 6 5 4 3 2 1
输出样例:
1 2 3 4 5 6 7 8
- 存储结构:
链表。
- 算法基本思想:
直接选择排序。
# 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;
}
- 问题描述:
对N个关键字取整数的记录进行整序,以使所有关键字为非负数的记录排在关键字为负数的记录之前,要求使用最少的附加空间,且算法的时间复杂度为O(N)。
- 输入样例:
8
-1 1 -2 2 -3 3 -4 4
输出样例:
-1 -4 -2 -3 2 3 1 4
- 存储结构:
顺序表。
- 算法基本思想:
双指针移动。设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。
还债结束,正式回归。