01-复杂度1 最大子列和问题 (20分)
给定K个整数组成的序列{ N 1 , N 2 , ..., N K },“连续子列”被定义为{ N i , N i+1 , ..., N j },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:
数据1:与样例等价,测试基本正确性; 数据2:102个随机整数; 数据3:103个随机整数; 数据4:104个随机整数; 数据5:105个随机整数; 输入格式: 输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。
输出格式: 在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。
输入样例:
6
-2 11 -4 13 -5 -2
输出样例:
20
// 01-复杂度1 最大子列和问题 (20分)
int MaxSubseqSum(int A[], int N) {
int ThisSum = 0, MaxSum = 0;
for (int i = 0; i <= N - 1; i++) {
ThisSum += A[i];
if (ThisSum > MaxSum) {
MaxSum = ThisSum;
} else if (ThisSum < 0) {
// 当前和为负数不会对后续子列和增大有帮助 丢弃
ThisSum = 0;
}
}
return MaxSum;
}
01-复杂度2 Maximum Subsequence Sum (25分)
Given a sequence of K integers { N 1 , N 2 , ..., N K }. A continuous subsequence is defined to be { N i , N i+1 , ..., N j } where 1≤i≤j≤K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.
Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.
Input Specification: Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (≤10000). The second line contains K numbers, separated by a space.
Output Specification: For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.
Sample Input:
10
-10 1 2 3 4 -5 -23 3 7 -21
Sample Output:
10 1 4
int MaxSubseqSumTest(int A[], int N) {
int ThisSum = 0, MaxSum = 0, start = 0, end = 0;
int AllNegative = 1;
int temp = 0;
for (int i = 0; i <= N - 1; i++) {
if (A[i] >= 0) {
AllNegative = 0;
}
ThisSum += A[i];
if (ThisSum > MaxSum) {
MaxSum = ThisSum;
end = A[i];
// MARK
for (int j = temp; j <= i; j++) {
if (A[j] > 0) {
start = A[j];
break;
}
}
} else if (ThisSum < 0) {
// 当前和为负数不会对后续子列和增大有帮助 丢弃
ThisSum = 0;
// MARK
temp = i;
}
}
if (AllNegative == 1) {
start = A[0];
end = A[N-1];
}
printf("%d %d %d", MaxSum, start, end);
return MaxSum;
}
01-复杂度3 二分查找 (20分)
本题要求实现二分查找算法。
函数接口定义: Position BinarySearch( List L, ElementType X );
其中List结构定义如下:
typedef int Position; typedef struct LNode List; struct LNode { ElementType Data[MAXSIZE]; Position Last; / 保存线性表中最后一个元素的位置 */ };
L是用户传入的一个线性表,其中ElementType元素可以通过>、==、<进行比较,并且题目保证传入的数据是递增有序的。函数BinarySearch要查找X在Data中的位置,即数组下标(注意:元素从下标1开始存储)。找到则返回下标,否则返回一个特殊的失败标记NotFound。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
#define NotFound 0
typedef int ElementType;
typedef int Position;
typedef struct LNode *List;
struct LNode {
ElementType Data[MAXSIZE];
Position Last; /* 保存线性表中最后一个元素的位置 */
};
List ReadInput(); /* 裁判实现,细节不表。元素从下标1开始存储 */
Position BinarySearch( List L, ElementType X );
int main()
{
List L;
ElementType X;
Position P;
L = ReadInput();
scanf("%d", &X);
P = BinarySearch( L, X );
printf("%d\n", P);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例1:
5
12 31 55 89 101
31
输出样例1:
2
输入样例2:
3
26 78 233
31
输出样例2:
0
答案如下:
Position BinarySearch( List L, ElementType X ) {
Position left = 1, right = L->Last;
Position middle = (left + right) / 2;
while (L->Data[middle] != X && left <= right) {
if (L->Data[middle] > X) {
right = middle - 1;
} else if (L->Data[middle] < X) {
left = middle + 1;
}
middle = (left + right) / 2;
}
if (L->Data[middle] == X) {
return middle;
}
return NotFound;
}
02-线性结构1 两个有序链表序列的合并 (15分)
本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。
函数接口定义:
List Merge( List L1, List L2 );
其中List结构定义如下:
typedef struct Node *PtrToNode;
struct Node {
ElementType Data; /* 存储结点数据 */
PtrToNode Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */
L1和L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Merge要将L1和L2合并为一个非递减的整数序列。应直接使用原序列中的结点,返回归并后的带头结点的链表头指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
ElementType Data;
PtrToNode Next;
};
typedef PtrToNode List;
List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表;空链表将输出NULL */
List Merge( List L1, List L2 );
int main()
{
List L1, L2, L;
L1 = Read();
L2 = Read();
L = Merge(L1, L2);
Print(L);
Print(L1);
Print(L2);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
3
1 3 5
5
2 4 6 8 10
输出样例:
1 2 3 4 5 6 8 10
NULL
NULL
02-线性结构2 一元多项式的乘法与加法运算 (20分)
设计函数分别求两个一元多项式的乘积与和。
输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式: 输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
#include <stdio.h>
#include <stdlib.h>
// 02-线性结构2 一元多项式的乘法与加法运算 (20分)
typedef struct PolyNode *Polynomial; // 多项式节点
struct PolyNode {
int coef; // 系数
int expon; // 指数
Polynomial link;
};
void Attach(int coef, int expon, Polynomial *pRear) {
Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
P->coef = coef;
P->expon = expon;
(*pRear)->link = P;
*pRear = P;
}
Polynomial ReadPoly() {
Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
Polynomial Rear = P;
int N;
scanf("%d", &N);
while (N--) {
int coef = 0, expon = 0;
scanf("%d %d", &coef, &expon);
Attach(coef, expon, &Rear);
}
Rear = P->link;
free(P);
return Rear;
}
// 系数和指数取上限,结果有零多项式没有通过 (P->link = NULL;)
Polynomial Add( Polynomial P1, Polynomial P2 ) {
Polynomial h1 = P1, h2 = P2;
Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
// Mark
P->link = NULL;
Polynomial Rear = P;
while (h1 && h2) {
if (h1->expon > h2->expon) {
Attach(h1->coef, h1->expon, &Rear);
h1 = h1->link;
} else if (h1->expon == h2->expon) {
if (h1->coef + h2->coef != 0) { // 系数之和不为0
Attach(h1->coef + h2->coef, h1->expon, &Rear);
}
// Mark
h1 = h1->link;
h2 = h2->link;
} else {
Attach(h2->coef, h2->expon, &Rear);
h2 = h2->link;
}
}
while (h1) {
Attach(h1->coef, h1->expon, &Rear);
h1 = h1->link;
}
while (h2) {
Attach(h2->coef, h2->expon, &Rear);
h2 = h2->link;
}
Rear = P->link;
free(P); // 释放头结点
return Rear;
}
Polynomial Mult( Polynomial P1, Polynomial P2 ) {
Polynomial h1 = P1, h2 = P2;
Polynomial Q = NULL;;
while (h1) {
Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
Polynomial Rear = P;
h2 = P2;
while (h2) {
Attach(h1->coef * h2->coef, h1->expon + h2->expon, &Rear);
h2 = h2->link;
}
Rear = P->link; // 尾部换到头部
free(P);
Q = Add(Q, Rear);
h1 = h1->link;
}
return Q;
}
void PrintPoly( Polynomial P ) {
if (!P) {
printf("0 0");
}
int flag = 0;
while (P) {
if (!flag) {
flag = 1;
} else {
printf(" ");
}
printf("%d %d", P->coef, P->expon);
P = P->link;
}
printf("\n");
}
int main()
{
Polynomial P1 = ReadPoly();
Polynomial P2 = ReadPoly();
Polynomial P3 = Add(P1, P2);
Polynomial P4 = Mult(P1, P2);
PrintPoly(P4);
PrintPoly(P3);
return 0;
}
02-线性结构3 Reversing Linked List (25分)
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.
Input Specification: Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤10 5 ) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address is the position of the node, Data is an integer, and Next is the position of the next node.
Output Specification: For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100000
typedef int Ptr;
//结构数组模拟链表
struct node{
int key;
Ptr next;
}list[MaxSize];
//逆转某一段含K个结点的链表
Ptr Reverse ( Ptr head, int K ) {
Ptr New, Old, Tmp; //New指向逆转链表表头,Old指向未逆转表头,Tmp记录Old后一个结点
int cnt = 1;
New = head;
Old = list[New].next;
while ( cnt < K ) {
Tmp = list[Old].next; //记录Old下一个结点,防止逆转指针后丢失
list[Old].next = New; //逆转指针
New = Old; Old = Tmp; //New,Old向后转移一个
cnt++;
}
list[head].next = Old; //原来的第一个结点逆转后变为最后一个结点,并连接剩下未逆转的元素
return New;
}
//判断是否需要逆转
int NeedReverse ( Ptr head , int K) {
int i;
for( i = 1; list[head].next != -1; head = list[head].next ) {
i++;
if ( i == K ) return 1; //还有K个或以上结点,需要逆转
}
return 0; //不足K个结点,不需要逆转
}
//逆转整个链表
Ptr ReversingLinkedList( Ptr head , int K ) {
Ptr UnreversedHead = head; //未逆转的链表的第一个结点
Ptr ListHead; //整个表的第一个结点
Ptr TempTail; //临时表尾,用来连接下一段逆转的链表
if ( NeedReverse( UnreversedHead, K ) ) { //第一次先判断是否需要逆转
ListHead = Reverse( UnreversedHead, K ); //记住逆转后的整个链表的第一个结点
TempTail = UnreversedHead; //记录此逆转链表的表尾
UnreversedHead = list[TempTail].next; //记录未逆转链表的表头
}
else //链表结点个数小于K,无需逆转
return head;
while ( NeedReverse( UnreversedHead, K ) ) {
list[TempTail].next = Reverse( UnreversedHead, K ); //上一个逆转链表的表尾与这个逆转链表的表头连接
TempTail = UnreversedHead;
UnreversedHead = list[TempTail].next;
}
return ListHead;
}
//输出链表
void PrintLinkedList ( Ptr head ) {
Ptr temp = head;
for(; list[temp].next != -1; temp = list[temp].next)
printf("%05d %d %05d\n", temp, list[temp].key, list[temp].next);
printf("%05d %d %d\n", temp, list[temp].key, list[temp].next);
}
int main(){
Ptr ad, head;
int N, K;
scanf("%d %d %d", &head, &N, &K);
for(int i = 0; i < N; i++){
scanf("%d", &ad);
scanf("%d %d", &list[ad].key, &list[ad].next);
}
PrintLinkedList( ReversingLinkedList( head, K ) );
return 0;
}
错误示例
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100000
struct CNode {
int data;
int next;
};
typedef struct CNode *PtrNode;
void printfCnode(struct CNode datas[], int h) {
int pre = h;
while (h != -1) {
if (datas[h].next == -1) {
printf("%05d %d %d\n", pre, datas[h].data, datas[h].next);
} else {
printf("%05d %d %05d\n", pre, datas[h].data, datas[h].next);
}
pre = datas[h].next;
h = pre;
}
}
int reverseCnodeWhenK(struct CNode datas[], int k, int h) {
if (k <= 1) {
return h;
}
// datas[h]
int front = datas[h].next, nextFront = datas[front].next;
struct CNode head;
head.next = h;
int num = 0;
int p = h;
// 输出头部
int flag = 0, pHead = h;
while (p != -1) {
num++;
if (num % k == 0) { // 找到尾部
num = 0;
while (++num < k) {
nextFront = datas[front].next;
datas[front].next = head.next;
head.next = front;
front = nextFront;
}
if (!flag) {
flag = 1;
pHead = head.next;
}
num = 0;
while (++num < k) { // head指向K循环最后一个元素
head.next = datas[head.next].next;
}
// K指向K+1
datas[head.next].next = front;
head.next = front;
p = front;
} else {
p = datas[p].next;
}
}
return pHead;
}
int main()
{
struct CNode datas[MaxSize];
int head; // 头部位置
int n; // 总输入个数
int k; // k个逆转
scanf("%d %d %d", &head, &n, &k);
// x索引位置 y值 z下一个索引
int i = 0, x, y, z;
while (i < n) {
scanf("%d %d %d", &x, &y, &z);
datas[x].data = y;
datas[x].next = z;
i++;
}
int h = reverseCnodeWhenK(datas, k, head);
printfCnode(datas, h);
return 0;
}
02-线性结构4 Pop Sequence (25分)
Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, ..., N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.
Input Specification: Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.
Output Specification: For each pop sequence, print in one line "YES" if it is indeed a possible pop sequence of the stack, or "NO" if not.
Sample Input:
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
Sample Output:
YES
NO
NO
YES
NO
创建一个栈Stack保存入栈元素
两个指针inputI指向入栈序列首个元素outputI指向出栈序列首个元素
1.若inputI指向元素等于outputI指向元素 inputI元素则进行了入栈出栈操作
此时如果栈已经满了则无法压入当前入栈元素报错 否则outputI inputI各后移一位
2.若inputI指向元素不等于outputI指向元素 去栈顶取元素和outputI指向元素比较
如果相等outputI后移一位 栈弹出元素
如果不等则把inputI指向的元素入栈,此时需要判别栈是否满,inputI指向元素是否已经走完
如若栈满inputI指向元素是否已经走完则当前出栈序列不是合法出栈序列
3.如果栈空inputI outputI都走完也没有出现错误 则是一个合法序列
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MaxSize1 1000
typedef int ElementType;
typedef int Position;
// 顺序栈
typedef struct SNode *Stack;
struct SNode {
ElementType *Data;
Position Top;
int MaxSize;
};
Stack CreateStack( int MaxSize );
bool IsFull( Stack S );
bool Push( Stack S, ElementType X );
bool IsEmpty( Stack S );
ElementType Pop( Stack S );
ElementType TopElement( Stack S );
int main()
{
int M, N, K;
int list[MaxSize1][MaxSize1] = {0};
M = N = K = 0;
scanf("%d %d %d", &M, &N, &K);
// 读入数据
for (int i = 0; i < K; i++) {
for (int j = 0; j < N; j++) {
scanf("%d", &list[i][j]);
}
}
int sequence[MaxSize1] = {0};
// 初始化顺序入栈数组
for (int i = 0; i < N; i++) {
sequence[i] = i + 1;
}
for (int i = 0; i < K; i++) {
int outputI = 0, inputI = 0;
Stack S = CreateStack(M);
while (outputI < N) {
if (inputI == N) { // 元素都已入栈
if (list[i][outputI] != TopElement(S)) {
printf("NO\n");
break;
} else {
outputI++;
Pop(S);
}
} else if (list[i][outputI] == sequence[inputI]) {
if(IsFull(S)) {
printf("NO\n");
break;
}
outputI++;
inputI++;
} else if (list[i][outputI] != sequence[inputI] && !IsEmpty(S) && list[i][outputI] == TopElement(S)) { // 不等取栈顶元素比较若相等输出指针右移
outputI++;
Pop(S);
} else if (!IsFull(S)) {
Push(S, sequence[inputI]);
inputI++;
} else {
printf("NO\n");
break;
}
}
if (outputI == N) {
printf("YES\n");
}
}
return 0;
}
Stack CreateStack( int MaxSize )
{
if (MaxSize <= 0) {
}
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Data = (ElementType *)malloc(sizeof(ElementType) * MaxSize);
S->Top = -1;
S->MaxSize = MaxSize;
return S;
}
bool IsFull( Stack S )
{
return (S->Top == S->MaxSize - 1);
}
bool Push( Stack S, ElementType X )
{
if (IsFull(S)) {
printf("堆栈已满无法压入");
return false;
}
S->Data[++(S->Top)] = X;
return true;
}
bool IsEmpty( Stack S )
{
return (S->Top == -1);
}
ElementType Pop( Stack S )
{
if (IsEmpty(S)) {
printf("堆栈已空无法弹出");
return false;
}
return S->Data[(S->Top)--];
}
ElementType TopElement( Stack S ) {
return S->Data[S->Top];
}
03-树1 树的同构 (25分)
给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
图1
图2
现给定两棵树,请你判断它们是否是同构的。 输入格式: 输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。
输出格式: 如果两棵树是同构的,输出“Yes”,否则输出“No”。
//
// main.c
// DataStruct
//
// Created by DC on 2020/2/25.
// Copyright © 2020 DC. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MaxTree 10
typedef char ElementType;
typedef int Tree;
struct TreeNode {
ElementType Data;
Tree Left, Right;
};
Tree BuildTree(struct TreeNode T[])
{
int N = 0, Root = -1;
ElementType Left, Right;
scanf("%d\n", &N);
int checkEmpty[MaxTree] = {0};
for (int i = 0; i < N; i++) {
scanf("%c %c %c\n", &T[i].Data, &Left, &Right);
if (Left != '-') {
T[i].Left = Left - '0';
checkEmpty[T[i].Left] = 1;
} else {
T[i].Left = -1;
}
if (Right != '-') {
T[i].Right = Right - '0';
checkEmpty[T[i].Right] = 1;
} else {
T[i].Right = -1;
}
}
for (int i = 0; i < N; i++) {
if (!checkEmpty[i]) {
Root = i;
break;
}
}
return Root;
}
/*
递归比较
代码顺序非常重要 之前把步骤三放在最前面导致错误
1.根为空 比较完成 成功
2.根子树长度不等 失败
3.根是否相等
4.根指向的左子树相等 根1的左子树和根2的左子树 根1的右子树和根2的右子树比较
5.根指向的左子树不相等 根1指向的左子树根2指向的右子树相等 根1的左子树和根2的左子树 根1的右子树和根2的右子树比较
*/
bool IsomorphismTree(struct TreeNode R1[], Tree Root1, struct TreeNode R2[], Tree Root2) {
if (Root1 == -1 && Root2 == -1) { // 比较完成
return true;
} else if ((Root1 != -1 && Root2 == -1) || (Root1 == -1 && Root2 != -1)) { // 树高度不一致
return false;
} else if (R1[Root1].Data != R2[Root2].Data) { // 根节点不等
// MARK根节点比较得后置 因为Root1 == -1 或者 Root2 == -1 Data仍然有脏数据
return false;
} else if (R1[Root1].Left == -1 && R2[Root2].Left == -1) {
return IsomorphismTree(R1, R1[Root1].Right, R2, R2[Root2].Right);
} else if (R1[R1[Root1].Left].Data == R2[R2[Root2].Left].Data) {
// 根节点指向的左子树元素相等 没有交换
return IsomorphismTree(R1, R1[Root1].Left, R2, R2[Root2].Left) && IsomorphismTree(R1, R1[Root1].Right, R2, R2[Root2].Right);
} else if (R1[R1[Root1].Left].Data == R2[R2[Root2].Right].Data) {
// 需要交换
return IsomorphismTree(R1, R1[Root1].Left, R2, R2[Root2].Right) && IsomorphismTree(R1, R1[Root1].Right, R2, R2[Root2].Left);
}
return false;
}
int main()
{
struct TreeNode R1[MaxTree], R2[MaxTree];
Tree Root1 = BuildTree(R1);
Tree Root2 = BuildTree(R2);
bool result = IsomorphismTree(R1, Root1, R2, Root2);
if (result) {
printf("Yes");
} else {
printf("No");
}
return 0;
}
03-树2 List Leaves (25分)
Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.
Input Specification: Each input file contains one test case. For each case, the first line gives a positive integer N (≤10) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a "-" will be put at the position. Any pair of children are separated by a space.
Output Specification: For each test case, print in one line all the leaves' indices in the order of top down, and left to right. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.
Sample Input:
8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6
Sample Output:
4 1 5
答案
//
// main.c
// DataStruct
//
// Created by DC on 2020/2/25.
// Copyright © 2020 DC. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MaxTree 10
typedef int Tree;
struct TreeNode {
Tree Left, Right, Data;
};
typedef int Position;
struct QNode {
Tree *Data; /* 存储元素的数组 */
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef struct QNode *Queue;
Queue CreateQueue( int MaxSize )
{
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Rear = 0;
Q->Front = 0;
Q->Data = (Tree *)malloc(sizeof(Tree) * MaxSize);
Q->MaxSize = MaxSize;
return Q;
}
bool QueueIsFull( Queue Q )
{
return ((Q->Rear + 1) % Q->MaxSize == Q->Front);
}
bool QueueIsEmpty( Queue Q )
{
return (Q->Rear == Q->Front);
}
bool AddQ( Queue Q, Tree X )
{
if(QueueIsFull(Q)) {
printf("队列已满");
return false;
}
Q->Data[Q->Rear] = X;
Q->Rear = (++Q->Rear) % Q->MaxSize;
return true;
}
Tree DeleteQ( Queue Q )
{
if (QueueIsEmpty(Q)) {
printf("队列已空");
return false;
}
Tree Data = Q->Data[Q->Front];
Q->Front = (++Q->Front) % Q->MaxSize;
return Data;
}
void levelTraversal(Tree Root, struct TreeNode list[], int leavesCount) {
Queue Q = CreateQueue(MaxTree);
if (Root != -1) {
AddQ(Q, Root);
}
while (!QueueIsEmpty(Q)) {
Tree T = DeleteQ(Q);
if (list[T].Left == -1 && list[T].Right == -1) {
leavesCount--;
if (leavesCount == 0) { // 最后一个叶子节点不输出空格
printf("%d", list[T].Data);
} else {
printf("%d ", list[T].Data);
}
}
if (list[T].Left != -1) {
AddQ(Q, list[T].Left);
}
if (list[T].Right != -1) {
AddQ(Q, list[T].Right);
}
}
}
int main() {
int N;
Tree Root = -1;
char Left, Right;
scanf("%d\n", &N);
struct TreeNode list[MaxTree];
// 查找根节点
int check[MaxTree] = {0};
// 记录叶子节点数量
int leavesCount = 0;
for (int i = 0; i < N; i++) {
// 读入数据
list[i].Data = i;
scanf("%c %c\n", &Left, &Right);
if (Left == '-') {
list[i].Left = -1;
} else {
list[i].Left = Left - '0';
check[list[i].Left] = 1;
}
if (Right == '-') {
list[i].Right = -1;
} else {
list[i].Right = Right - '0';
check[list[i].Right] = 1;
}
if (Left == '-' && Right == '-') { // 叶子节点加1
leavesCount++;
}
}
for (int i = 0; i < N; i++) {
if (!check[i]) { // 找到根节点
Root = i;
break;
}
}
levelTraversal(Root, list, leavesCount);
}