1.leetcode

1
2
3
4
5
6
// 弹出 x 的末尾数字 digit
digit = x % 10
x /= 10

// 将数字 digit 推入 rev 末尾
rev = rev * 10 + digit

例题:力扣7:回文数(逆序数字)

也是西南交大2005年程序题第1题

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
int reverse(int x) {
long outcome=0;
while(x)
{
int i=x%10; //从给定数字中每次取出个位数
outcome=outcome*10+i; //将取出的个位每次加到新给定的整数后面
x/=10; //将给定数字整体降位
}
return outcome<INT_MIN || outcome>INT_MAX?0:outcome; //判断逆置后是否超出整数范围
}
};

2.王道

3.天勤

例6-1:求二叉树存储的算术表达式的值

题目:表达式存储在二叉树中,编写算法求值。

1628590460929

分析:先求左再求右,读取根结点符号,计算值。所以采用后序遍历

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
typedef	struct BTNode
{
struct BTNode* lchild, * rchild;
char data;
}BTNode;

int op(int A, int B, char C) {}; //返回以C为运算符,以A,B为操作数的算式的数值

int comp(BTNode* p)
{
int A, B;
if (p == NULL) //空树返回0
{
return 0;
}

if (p->lchild == NULL && p->rchild == NULL) //走到叶子结点
{
return p->data - '0'; //叶子结点,为数值,直接转换
}

A = comp(p->lchild); //后序遍历求左子树
B = comp(p->rchild); //后序遍历求右子树
return op(A, B, p->data);
}

例6-3:找指定结点(剪枝操作)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
typedef	struct BTNode
{
struct BTNode* lchild, * rchild;
char data;
}BTNode;

void Search(BTNode* p, BTNode*& q, int key) //q为引用型指针,因为q要改变
{
if (p == NULL)
{
return;
}
if (p->data == key)
{
q = p;
}
else
{
Search(p->lchild, q, key);
if (q == NULL) //左子树没找到才到右子树中查找,剪枝操作
{
Search(p->rchild, q, key);
}
}
}

例6-3:求二叉树宽度

宽度:结点数最多一层上的结点个数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#define maxSize 100

typedef struct BTNode
{
struct BTNode* lchild, * rchild;
char data;
}BTNode;

typedef struct //非循环队列的队列元素,存储结点指针以及层号
{
BTNode* p;
int lno; //结点层号
}St;

int MaxNode(BTNode* b)
{
St que[maxSize]; //定义顺序非循环队列
int front = 0, rear = 0;

int Lno = 0, i, j, n, max = 0;
BTNode* q; //接收出队元素

if (b != NULL)
{
++rear;
que[rear].p = b; //树根入队
que[rear].lno = 1; //层号为1

while (front != rear)
{
++front;
q = que[front].p; //出队
Lno = que[front].lno; //获取出队元素层号信息
if (q->lchild != NULL) //左不空,入队
{
++rear;
que[rear].p = q->lchild;
que[rear].lno = Lno + 1; //层号+1
}
if (q->rchild != NULL) //右不空,入队
{
++rear;
que[rear].p = q->lchild;
que[rear].lno = Lno + 1;
}
}

for (i = 1; i <= Lno; i++) //现在Lno数值为最大层数
{
n = 0; //存储每层结点个数
for (j = 0; j < rear; j++) //编列队列数组
{
if (que[j].lno == i)
{
++n;
}
}

if (max < n) //max存最大结点个数,读完一层比较一次
{
max = n;
}
}
return max;
}
else //空树,直接返回0
return 0;
}

缺陷:效率不太好,还可以优化

习题2.1.5:填充parent域

题目:二叉树增加parent域,设计算法给每个结点parent域赋值,并输出所以结点到根结点路径

分析:给parent赋值可以在遍历时传入父节点指针

​ 打印路径即找到结点一直访问parent域

​ 打印全部路径采用遍历方式来完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<stdio.h>
#include<malloc.h>
#include <iostream>
using namespace std;

typedef struct BTNode
{
struct BTNode* lchild, * rchild, * parent;
char data;
}BTNode;

void triBtree(BTNode* p, BTNode* q) //给各个结点parent赋值,q指向p的双亲结点
{
if (p != NULL)
{
p->parent = q;
q = p;
triBtree(p->lchild, q);
triBtree(p->rchild, q);
}
}

void printPath(BTNode* p) //打印路径
{
while (p != NULL)
{
cout << p->data << " " << endl;
p = p->parent;
}
}

void allpath(BTNode* p) //遍历打印全部路径
{
if (p != NULL)
{
printPath(p);

allpath(p->lchild);
allpath(p->rchild);
}
}


习题2.1.7:输出指定结点层号

分析:看书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<stdio.h>
#include<malloc.h>
#include <iostream>
using namespace std;

typedef struct BTNode
{
struct BTNode* lchild, * rchild;
char data;
}BTNode;

int L = 1; //全局变量,记录层数
void leno(BTNode* p, char x)
{
if (p != NULL)
{
if (p->data == x)
{
cout << L << endl;
}
}
++L; //向下访问,层数增加
leno(p->lchild, x);
leno(p->rchild, x);
--L; //返回上层,层数减少
}

习题2.2.1:输出根结点到每个叶子结点路径

分析:看书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<stdio.h>
#include<malloc.h>
#include <iostream>
using namespace std;

#define maxSize 50

typedef struct BTNode
{
struct BTNode* lchild, * rchild;
char data;
}BTNode;

int i;
int top=0;
char pathStack[maxSize]; //数组模拟路径栈
void allpath(BTNode* p)
{
if (p != NULL)
{
pathStack[top++] = p->data; //向下访问结点并入栈
if (p->lchild == NULL && p->rchild == NULL) //叶子结点,输出栈元素
{
for (i = 0; i < top; i++)
{
cout << pathStack[i];
}
}

allpath(p->lchild);
allpath(p->rchild);
--top; //返回上层,元素退栈
}
}

4.西南交大2005年840程序题

第2题:求字符串中出现整数个数

错误:-号在数字中间和数字末尾会输出错误

题目:输入一个字符串,内有数字和非数字字符,如b56x6g*6454er790v将其中连续数字作为一个长整型数依次存入数组a中,例:56存入a[0],6存入a[1]。。。统计有多少整数,并输出。假设不存在溢出情况,字符串中存在“-”号要将其后数字看作负数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include<stdio.h>
#include<string.h>
#include<ctype.h>

int myatoi2(char* a)
{
if(a[0]!='-') //正整数转换
{
int len=strlen(a),i,j,n=0;
int sum=0;
for(i=0;i<len;i++)
{
int bitsum;
bitsum=a[i]-'0';
for(j=0;j<len-i-1;j++)
{
bitsum*=10;
}
sum+=bitsum;
}
return sum;
}
else if(a[0]=='-' && a[1]>='0'&&a[1]<='9') //正常负号转换
{
return -myatoi2(&(a[1]));
}
else //消除连续负号影响
{
return myatoi2(&(a[1]));
}
}

void getnum(char* str,int* num)
{
int i=0,j=0,k=0,m=0;
char temp[10]={0};
while(str[i]!='\0')
{
if(str[i]>='0'&&str[i]<='9'||str[i]=='-')
{
if(m!=0&&str[i]=='-') //消除数字中间负号影响
{
if(m!=1) //消除连续负号影响
{
num[k++]=myatoi2(temp);
}
memset(temp,0,10); //C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。
j=0;
m=0;
continue;
}
m++;
temp[j++]=str[i];
}
else if((str[i-1]>='0' && str[i-1]<='9')) //如果当前不是数字然后前一位是数字
{
num[k++]=myatoi2(temp);
memset(temp,0,10);
j=0;
m=0;
}
i++;
}
if(j!=0)
num[k++]=myatoi2(temp);
}

void main()
{
int numarr[4],i;
char *arr="abc---897def-67890is9876asd34jmk";
getnum(arr,numarr);
for(i=0;i<4;i++)
{
printf("%d ",numarr[i]);
}
}

5.西南交大2006年840程序题

第2题:返回正整数指定某位数

题目:编写函数Digit(int n,int k),函数返回正整数n左起第k位数,若位数不够返回-1

例如:Digit(31415926,6)=9

​ Digit(3141,5)=-1

原理:将数字从低位到高位拆分一个一个放进数组,再利用数组下标来定位具体位数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int Digit(int n,int k)
{
char ch[10];
int value,index=0;
while((value=n%10)!=0) //每次从低到高取一位数字
{
ch[index]=value;
n=n/10; //移掉最低位
index++; //数组指针后移
}
if(k>index||k==0) //k大于数字位数或者等于0
{
return -1;
}
return ch[index-k];
}

第4题:统计单词

题目:编写程序,从键盘输入一个文本文件名和一个单词,统计在文件中有多少个这样的单词(不区分大小写)

示例:输入:aBc

​ 文件内容(2行):123Abc abc abcd

​ ABC 7Ashd

​ 输出:2

示例:输入:123aBc

​ 文件内容(2行):123aBc abc 12

​ 3aBC 7Ashd

​ 输出:1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<stdio.h>
#include<ctype.h>

void main()
{
char s[100]; //文件中读出来的字符串
char a[100]; //输入的字符串
int i=0,j=0;
int num=0; //统计
FILE *p=fopen("1.txt","r+");
if(p==NULL)
{
printf("err");
return;
}
printf("suc\n");
printf("please enter string:");
scanf("%s",a);
for(j=0;j<strlen(a);j++) //将键盘输入的字符串变成全小写
{
if(isupper(a[j]))
{
a[j]+=32;
}
}
//printf("%s",a);
printf("\n");
while(!feof(p))
{
for(i=0;!feof(p);i++) //一个一个字符读取,读到字符结束就把存放字符串的数组拿去比较
{
char t=fgetc(p);
if(t==' '||t=='\t'||t=='\n'||feof(p)) //文件结尾必须也要加入判断条件并补上末尾\0,否则后面字符串比对最后一个字符会失败
{
s[i]='\0';
break;
}
if(isupper(t)) //将文本中读出来的字符串变成全小写
{
t=t+32;
}
s[i]=t;
}
//printf("%s\n",s);
if(strcmp(s,a)==0) //比对
{
num++;
}
}
fclose(p);
printf("%d",num);
printf("\n");
}

第5题:叶子节点数

题目:递归求二叉树叶子结点数

1
2
3
4
5
6
7
8
9
void Num(BTNode *BT)
{
if(BT==NULL)
return 0;
if(BT->left==NULL && BT->right==NULL)
return 1;
else
return Num(BT->left)+Num(BT->right);
}

6.西南交大2007年840程序题

第1题:迭代求平方根

题目:用迭代法求a的平方根,迭代公式:x[n+1]=(x[n]+a/x[n]),要求前后两次绝对值差小于10的-5次方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>

void main()
{
double a,b,x;
printf("please enter a number(>0) to get sqrt:");
scanf("%lf",&x);
a=1.0;
while((fabs(a-b)>1e-5))
{
b=a;
a=(b+x/b)/2;
}
printf("the sqrt is:%0.3lf\n",b);
}

牛顿迭代法:大致就是通过迭代公式求a b,当a b足够接近时b值即为所求平方根

第3题:求素因子乘积

题目:从键盘输入任意一个大于等于2的自然数m,将m写成所有素因子乘积的形式

如:输入:13 输出:13=13

​ 420 420=22357

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h>

void main()
{
int x,i;
printf("please enter a num(>=2):");
scanf("%d",&x);
printf("%d=",x);
for(i=2;i<=x;i++)//本身是素数的情况最大也就是本身
{
while(x%i==0) //将输入数从2开始慢慢取余看能否除尽,能则除并输出除数。这里由于从2开始一个一个除,固后面i即使增加也不可能出现2的倍数,即也筛掉了合数
{
x/=i;
if(x==1)//除i为1,即此时x为素数,i为他本身
{
printf("%d",i);
break;
}
printf("%d*",i);
}
}
printf("\n");
}

第5题:二叉排序树判断

判断给定二叉树是否为二叉排序树。

王道p191 6

原理:中序遍历看是否递增有序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
KeyType preat=-32767; //全局变量,保存当前中序前驱的值,初始为-∞

int JudgeBST(BiTree bt)
{
int b1,b2;
if(bt==NULL)
{
return 1;
}
else
{
b1=JudgeBST(bt->lchild); //判左,左边整体没问题返回1

if(b1==0 || predt>=bt->data) //若左子树返回0或前驱大于等于当前结点,则不是二叉排序树
{
return 0;
}
predt=bt->data; //保存当前结点关键字


b2=JudgeBST(bt->rchild); //判右,右边整体没问题返回1
return b2; //返回右子树结果,前面程序走完如果左子树有问题则会提前返回0,走不到这步,而走到这步表示前面左子树没问题,所以返回右子树的结果,右子树为1则整体没问题,右子树为0则右子树有问题,同时,整体也有问题。
}
}

7.西南交大2008年840程序题

第4题:求二叉树高度

题目:设计算法求二叉树高度

1
2
3
4
5
6
7
8
9
10
11
12
//后序遍历求高度
int Depth(BiTree &T)
{
int m,n;
if(!T) //树空
{
return 0;
}
m=Depth(T->lchild); //左子树高度
n=Depth(T->rchild); //右子树高度
return (m>n?m:n)+1; //回退,加上当前层高度再回退
}

2012 840

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<stdio.h>
#include<string.h>

void main()
{
char c;
char s[100];
int i=0,l=0,h=0;
while((c=getchar())!='@')
{
s[i++]=c;
}
s[i]='\0';
h=i-1;
while(l<h)
{
if(s[l++]!=s[h--])
{
printf("not hui wen\n");
break;
}
if(l>=h)
{
printf("hui wen\n");
}
}
}

8.西南交大2013年840程序题

第2题:打印指定字符画

题目:打印如下

1
2
3
  *
***
*****

到控制台和文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<stdio.h>

int main()
{
int n,i,j,l;
FILE* file = fopen("test.txt", "w");
printf("输入行数:");
scanf("%d", &n);

for (i = 0; i < n; i++)
{
for (j = 0; j < n - i; j++)
{
printf(" ");
fwrite(" ", 1, 1, file); //参数:(待写入数据起始地址、写入的数据类型长度、写入次数(个数),文件指针)
//fwrite以二进制形式对文件进行操作。用fwrite写入到文本中的内容,打开之后,字母可以正常显示,数字却显示“?”或是空格。以fread的方法读出,用printf打印出来是正常显示的。
//这里也可以用fprintf
//二进制写入会比格式化写入节省存储空间
}
for (l = 0; l < 2 * (i)+1; l++)
{
printf("*");
fwrite("*", 1, 1, file);
}
printf("\n");
fwrite("\n", 1, 1, file);
}
fclose(file);
}

第3题:为三叉链表存储结构的二叉树指定父节点

题目:编写算法,将所有结点的双亲结点指针域正确填充

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<stdio.h>

typedef struct node //二叉树采用三叉链表存储
{
char ch;
struct node* parent; //双亲结点
struct node* lchild;
struct node* rchild;
}TBTNode,*TBTPtr;


void FillParent(TBTPtr root) //类似对先序遍历进行的改造
{
TBTNode* temp = root;
if(temp==NULL)
{
return;
}

if (temp->lchild)
{
temp->lchild->parent = temp;
temp = temp->lchild;
FillParent(temp);
}
if (temp->rchild)
{
temp->rchild->parent = temp;
temp = temp->rchild;
FillParent(temp);
}
}

9.西南交大2014年程序题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
#include<math.h>

void main()
{
float i=1,j=1,sum=0,n=pow(10,-6);
while(fabs(4*i/j)>=n)
{
sum+=4*i/j;
i*=-1;
j+=2;
}
printf("%.4f",sum);
}

第2题:打印指定字符画

题目:打印如下

1
2
3
4
1
12
123
1234

到控制台和文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<stdio.h>

int main()
{
int n,i,j,l;
FILE* file = fopen("test.txt", "w");
printf("输入行数:");
scanf("%d", &n);

for (i = 0; i < n; i++)
{
for (j = 1; j <=i+1; j++)
{
printf("%d",j);
fprintf(file,"%d",j); //将格式化的数据写入文件。与 scanf() 和 printf() 相比,它们仅仅多了一个 fp 参数。
//这里不用fwrite是因为fwrite处理数字会乱码。但是能通过fread从乱码文件中获取到正确的信息
}
printf("\n");
fprintf(file,"\n");
}
fclose(file);
}

第3题:二叉树中查找指定结点

题目:二叉树中查找指定结点并返回地址,找不到返回NULL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<stdio.h>

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


BiTree Locate(BiTree bt, char key) //先序遍历.可以做模板记住,整体就是 遍历并一层层返回需要的某一个元素
{
BiTree p;
if (bt == NULL)
{
return NULL;
}
else if (bt->data == key)
{
return bt;
}
else
{
p = Locate(bt->lchild, key);
if (p)
{
return p;
}
else
{
return Locate(bt->rchild, key);
}
}
}

10.西南交大2017年840程序题

第2题:存储学生信息

题目:N个学生,信息有学号、姓名、三门课成绩、三门课平均分。从键盘输入前三个信息,平均分由输入算出,最后将结果存放到文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<stdio.h>
#include <malloc.h>

typedef struct Stu
{
//char* stuNum; //可以用成员指针来表示字符串,但结构体成员指针需要初始化,否则报错
char stuNum[20];
char name[20];
float score[3];
float avg;
}Stu;

void main()
{
int N;
FILE* file;
file = fopen("test.txt", "w");

printf("学生信息数量:");
scanf("%d", &N);

Stu* stus = (Stu*)malloc(sizeof(Stu) * N);
for (int i = 0; i < N; i++)
{
//stus[i].stuNum = (char*)malloc(sizeof(char)); //结构体成员指针初始化(无论存多少数据,初始化开辟一个对应空间即可)
printf("\n输入%d号学生信息(学号 姓名 三科成绩):", i);
scanf("%s %s %f %f %f", stus[i].stuNum, stus[i].name, &stus[i].score[0], &stus[i].score[1], &stus[i].score[2]);
stus[i].avg = (stus[i].score[0] + stus[i].score[1] + stus[i].score[2]) / 3;

fprintf(file, " %s %s %f %f %f %f\n", stus[i].stuNum, stus[i].name, stus[i].score[0], stus[i].score[1], stus[i].score[2],stus[i].avg);
}
fclose(file);
}

使用fwrite版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<stdio.h>
#include <malloc.h>

typedef struct Stu {
//char* stuNum; //可以用成员指针来表示字符串,但结构体成员指针需要初始化,否则报错
char stuNum[20];
char name[20];
float score[3];
float avg;
}Stu;

void main() {
int N;
FILE* file;
file = fopen("test.txt", "wb+");
printf("学生信息数量:");
scanf("%d", &N);
Stu* stus = (Stu*)malloc(sizeof(Stu) * N);
Stu* stus2 = (Stu*)malloc(sizeof(Stu) * N);
for (int i = 0; i < N; i++)
{
printf("\n输入%d号学生信息(学号 姓名 三科成绩):", i);
scanf("%s %s %f %f %f", stus[i].stuNum, stus[i].name, &stus[i].score[0], &stus[i].score[1], &stus[i].score[2]);
stus[i].avg = (stus[i].score[0] + stus[i].score[1] + stus[i].score[2]) / 3;
}

fwrite(stus, sizeof(Stu), N, file);
rewind(file);
fread(stus2, sizeof(Stu), N, file);

for (int i = 0; i < N; i++)
{
printf("%s %s %f %f %f", stus2[i].stuNum, stus2[i].name, stus2[i].score[0], stus2[i].score[1], stus2[i].score[2]);
}
fclose(file);
}

11.西南交大2014年959程序题

第10题(填空题):交换二叉树左右子树

题目:交换二叉树左右子树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<stdio.h>

typedef struct BiTNode
{
struct BiTNode* lchild, * rchild;
int value;
}*BiTree,BiTNode;

void Swap(BiTree bt)
{
if (bt == NULL)
{
return;
}
BiTree temp;
Swap(bt->lchild);
Swap(bt->rchild);

temp = bt->lchild;
bt->lchild = bt->rchild;
bt->rchild = temp;
}

第4题:复制二叉树

题目:将以t为树根二叉树复制到以bt为树根中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<stdio.h>
#include<malloc.h>

typedef struct BiTNode
{
struct BiTNode* lchild, * rchild;
int value;
}*BiTree, BiTNode;

void Copy(BiTree bt, BiTree& bt2) //只有c++有引用,引用即取别名。传指针其实只是复制了地址,从而对指向元素进行更改,但是如果向对实参指针地址进行更改则做不到
{
if (bt == NULL)
{
bt2 = NULL;
return;
}
bt2 = (BiTree)malloc(sizeof(BiTNode));
//bt2->lchild=null;
//bt2->rchild=null;
//bt2->lchild= (BiTree)malloc(sizeof(BiTNode)); //能连接起来的本质上原因
//原本一个结点就包含左右指针,但是没有赋值,无指向,在递归时将左右指针向下传递后,让其指向新申请空间,从而达到连接
bt2->value = bt->value;

Copy(bt->lchild, bt2->lchild);
Copy(bt->rchild, bt2->rchild);
}

补充:引用,传值区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<stdio.h>
#include<malloc.h>

void test(int* a)//传指针
{
printf("a_v:%d\n", *a);
printf("a:%p\n", a);
printf("&a:%p\n\n", &a);
}

void test2(int*& b)//传引用
{
printf("b_v:%d\n", *b);
printf("b:%p\n", b);
printf("&b:%p\n\n", &b);
}

void main()
{
int a = 10;
int* p = &a;
test(p);
test2(p);
printf("p_v:%d\n", *p);
printf("p:%p\n", p);
printf("&p:%p\n\n", &p);
}
1
2
3
4
5
6
7
8
9
10
11
12
输出:
a_v:10 //值
a:00F8FA9C
&a:00F8F9BC

b_v:10
b:00F8FA9C
&b:00F8FA90

p_v:10
p:00F8FA9C
&p:00F8FA90

显然,bp完全相同。ap只是指向相同,ap俩指针本身地址不同。指针传递本质上也是值传递,只是由于传的是指向地址,所以局部更改能返回到全局

创建二叉树:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<stdio.h>
#include <malloc.h>

typedef struct Node
{
char data;
struct Node* l, * r;
}BiNode, * BiTree;

void Create(BiTree &t)//先序创建二叉树
{
char c = getchar();
if (c != '#')
{
t = (BiTree)malloc(sizeof(BiNode));
t->data = c;
t->l = NULL;
t->r = NULL;

Create(t->l);
Create(t->r);
}
}

void preOrder(BiTree t) //中序遍历
{
if (t != NULL)
{
preOrder(t->l);
printf("%c ", t->data);
preOrder(t->r);
}
}

void main() {
BiTree t;
Create(t);
preOrder(t);
}

位运算

Brian Kernighan(可以用于清除二进制数中最右侧的1)

记 f(x)表示 x 和 x-1 进行与运算所得的结果(即 f(x)=x&(x-1),那么 f(x) 恰为 x 删去(变成0)其二进制表示中最右侧的 1 的结果。

求二进制最后一位

在循环的每一步中,我们可以使用位运算 n & 1 获取 n 的最低位,判断其是否为 1。在这之后,我们将 n 右移一位:n = n >> 1,这样在第 ii 步时,n & 1 得到的就是初始 n 的第 i 个二进制位。

整数转补码:

对于一个正整数x,如果x的类型大小是n位的二进制数,则x的补码为:2的n次方 - x

对于一个负整数x,x的补码为2的n次方+x

找重复子串

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

示例 1:

输入: s = “abab”
输出: true
解释: 可由子串 “ab” 重复两次构成。
示例 2:

输入: s = “aba”
输出: false
示例 3:

输入: s = “abcabcabcabc”
输出: true
解释: 可由子串 “abc” 重复四次构成。 (或子串 “abcabc” 重复两次构成。)

解法:我们将两个 ss 连在一起,并移除第一个和最后一个字符。如果 ss 是该字符串的子串,那么 ss 就满足题目要求。

字符串拼接效率问题

引申使用str += “a”, str =str+ “a” 效率差距:

str =str+ “a”加的运算产生的是一个新的对象,再把结果返回,而str += “a” 涉及到的应该是对象的引用,操作之后直接返回引用,避免了产生新的对象。因此,两者的性能有一定的差距。

单调栈

题目只要涉及:求大于某个数的第一个元素、下一个更大元素…这种类似的字眼的,都是单调栈的题目

对于求正因子,记住i*i<num这一条件

最大公因数gcd

1.__gcd在vs内没有,devcpp内有,头文件为#include

附上实现代码:

1
2
3
4
5
6
7
8
9
10
auto __gcd(auto a, auto b) {
auto r = 0;
while (a % b != 0)
{
r = a % b;
a = b;
b = r;
}
return b;
}

2.斐波那契数列最大公约数定理gcd(Fn, Fm) = F(gcd(n, m))

关于C/C++的四舍五入机制

1
2
3
4
5
6
int main()
{
printf("%0.1f\n", 0.55); //结果:0.6 保留小数位会四舍五入
printf("%0.1f\n", 0.54); //结果:0.5
printf("%d\n", 5 / 2); //结果:2 直接除则不会
}