数据结构期中代码注意事项(二叉树及之前)1-11

注意:链表为空。是否越界访问。每写一步都要思考该步是否会有越界(多/少)等问题。这一步是否有不能走的条件(删除的时候不为空)。只有该节点开辟了空间,该节点才能被指向。能用c++就用c++。#include <iostream>   #include <queue>   using namespace std;queue<int> ji,ou;。二叉树遍历过程中,注意递归终止条件是否会导致子树没有遍历就退出了,每一层返回的值要单独用一个变量保存下来。用顺序表访问二叉树的双亲、孩子节点时,一定要注意是否越界。最后数组大小别忘记++/--。

1.在循环中,最好让循环条件的变量代表的是当前元素,而不是当前元素的下一个位置

//不断插入一个元素,是最后生成的顺序表是有序顺序表:

2.创建单链表的方法:

注意:参数表中的链表要传引用;定义两个指针;一定要记得首先给L malloc一块空间。

当遇到输入不正常时,首先检查是否所有指针都开辟空间了。

3.切记有指针就一定要开辟空间。

4.一定要注意空指针域不能访问,一定要及时判断该节点或者该节点的下一个节点是否为空。

5.如果出错的时候:分析链表为空时、只有一个节点时、有两个节点时、有三个节点时......

* * * 带头结点的单链表就地逆置

//这种方法最简单

//headptr用来记录下一个midptr应该指向的节点

6.出现运行超时可能是链表出现了死循环。出现段错误大概率是数组越界访问了。

7.要求实现一个对数组进行循环右移的简单函数:一个数组a中存有n(>0)个整数,将每个整数循环向右移m(≥0)个位置,即将a中的数据由(a0​a1​⋯an−1​)变换为(an−m​⋯an−1​a0​a1​⋯an−m−1​)(最后m个数循环移至最前面的m个位置)。

前后两组分别逆置即可实现。注意:注意有m>n的情况,让m%=n。

8.不要忘记了前后指针法。

9.有时候让删除数据的时候,为了让代码简便,可以在这个结构体内部定义一个变量标记一下是否被删掉了,这样就可以不用删除了,打印的时候不打印就可以了。

10.

char* xuehao;   scanf("%s", xuehao);遇到空格就不读入了

#include <iostream> #include <string> string delet;cin>>delet;也是遇到空格就不读了

#include <stdio.h>    char str[100];   gets(str);可以读入空格

#include <iostream>  #include <string>  string str;   getline(cin, str);可以读入空格

while(scanf("%c",&s)&&s!='\n')可以输入一行字符

11.    #include <string.h>

        (strcmp(tmp, arr->stu[i].xuehao))//相等返回零,不相等返回正数

12.

//注意初始值最好弄成-1,而不是1
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>int main()
{int *a,*b;int ma=0;int c,d;a=(int*)malloc(10000*sizeof(int));//  b=(int*)malloc(10000*sizeof(int));int n,m;scanf("%d %d",&n,&m);for(int i=0;i<n;i++){scanf("%d",&c);if(c>ma)ma=c;a[c]=-1;//注意初始值最好弄成-1,而不是1}for(int i=0;i<m;i++){scanf("%d",&d);a[d]++;}int tmp=0;for(int i=0;i<=ma;i++)//注意是<={if(a[i]==-1){tmp=1;printf("%d ",i);}}if(tmp==0)printf("0");return 0;
}

13.链表后移p=p->next。  顺序表后移p++。

14.Status ListCreate_L(LinkList &L,int n):当需要改变参数时,记得要传引用。

15.对带头结点的单链表的就地逆置。

void ListReverse_L(LinkList &L)
{LinkList pre,pb,nex;pre=L;if(!L)exit(OVERFLOW);pb=L->next;//注意这个循环条件,因为循环内部对pb的next进行访问了//必须保证下一个也是非空指针//否则会出现段错误while(pb->next){nex=pb->next;pb->next=pre;pre=pb;pb=nex;}if(pb->next==NULL)pb->next=pre;L->next->next=NULL;L->next=pb;
}

16.

当创建了一个新链表时,一定记得实现开辟头结点的空间,让尾指针指向头节点,然后开辟每个结点的空间,尾指针的next指向该节点,尾指针后移。

当进行链表的合并时,注意链表的余块不要忘记处理。

17.求链表倒数第k个数:

另一个方法:双指针法,后指针位于第k个节点,前指针位于第一个节点。前后指针都后移,后指针走到结尾,前指针指向的位置就是倒数第k个。

注意:防止越界(假如有三个数,结果求倒数第八个)。

//count为倒数第几个,n为链表中有几个节点
void ListFind(li s,int count,int n)
{li ps=s->next;//别忘了假如有三个数,结果求倒数第八个if(count-n<0)//3 1 2 3 -1{printf("NULL");return;}for(int i=0;i<count-n;i++){//在其间走到空也要结束if(!ps){printf("NULL");return;}ps=ps->next;}if(ps)printf("%d",ps->e);elseprintf("NULL");
}

18.设有一个双向循环链表,每个结点中除有left、data和right三个域外,还增设了一个访问频度域freq,freq 的初值为零。每当链表进行一次查找操作后,被访问结点的频度域值便增1,同时调整链表中结点的次序,使链表按结点频度值非递增有序的次序排列。

typedef struct Node{
ElemType  data;struct Node *left;struct Node *right;
intfreq;
} DNode;
DNode *locate_DList(DNode *&L, ElemType x)
{ //在表L中查找元素x,查找成功则调整结点频度域值及结点位置,并返回结点地址;
//查找不成功则返回NULL
DNode *p=L, *q;if (L==NULL)  return NULL;while (p->data!=x && p->right!=L)  p=p->right;if (p->data!=x)  return NULL;p->freq++;q=p->left;while (q!=L && q->freq<=p->freq)  q=q->left;  //查找插入位置if (q==L && q->freq<=p->freq) {  //需将p结点插在头结点L前
//将p结点先从链表中摘下来
p->left->right=p->right;p->right->left=p->left;//将p结点插在L结点前p->right=L;p->left=L->left;L->left->right=p;L->left=p;L=p;}else if (q!=p->left ) {  //若q不是p的前驱,则需调整结点位置,将p结点插在q结点后
//将p结点先从链表中摘下来p->left->right=p->right;p->right->left=p->left;p->left=q;//将p结点插在q结点后p->right=q->right; q->right->left=p; q->right=p;}return p;
}

19.//在带头结点的双向链表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1。

20.删除循环单链表某个节点。注意循环边界条件。注意释放被删节点的空间。

void ListDelete_CL(LinkList &CL, ElemType min, ElemType max)
{LNode* p=CL->next;LNode* pre=CL;while(p!=CL){if(p->data>min&&p->data<max){pre->next=p->next;LNode* pp=p;free(pp);p=pre->next;}else{pre=pre->next;p=p->next;}}
}

21.双向循环链表操作集。

typedef int dataType;typedef struct _node
{dataType data;struct _node *prev;//指向前驱的指针struct _node *next;//指向后继的指针
}node;typedef node* List;#define OVERFLOW -2
#define OK 1
#define ERROR 0
//创建一个空的循环链表,返回指向头节点的指针。
List create_list()
{node* p=(node*)malloc(sizeof(node));if(!p)exit(OVERFLOW);p->next=p;p->prev=p;return p;
}
//用尾插法向链表L中插入数据域等于x的结点
void insert(List L, dataType x)
{node* p=(node*)malloc(sizeof(node));if(!p)exit(OVERFLOW);p->data=x;node* ppt=L;p->prev=ppt->prev;p->next=ppt;ppt->prev->next=p;ppt->prev=p;
}
//如果链表为空,则返回true,否则返回false。
bool is_empty(List L)
{if(L->next==L&&L->prev==L)return true;elsereturn false;
}
//顺序遍历链表L。输出所有结点的数据域。如果链表为空则输出NULL
void traverse(List L)
{node* p=L->next;if(L->next==L&&L->prev==L)printf("NULL\n");else{while(p!=L){printf("%d ",p->data);p=p->next;}printf("\n");}
}
//逆序遍历链表L。输出所有结点的数据域。如果链表为空则输出NULL
void traverse_back(List L)
{node* p=L->prev;if(L->next==L&&L->prev==L)printf("NULL\n");else{while(p!=L){printf("%d ",p->data);p=p->prev;}printf("\n");}
}
//返回第1个指向数据域等于x的结点的指针。如果没有则返回NULL。
node* search(List L, dataType x)
{node* p=L->next;while(p!=L){if(p->data==x){return p;}p=p->next;}return NULL;
}
//删除指针p指向的结点。调用者保证p是合法的。
//返回p指向结点后继结点的指针。
//若p指向链表最后一个结点,返回指向头结点的指针。
node* delete_node(List L, node* p)
{node* ptr=L->next;while(ptr!=L){if(ptr==p){node* pp=ptr->next;ptr->prev->next=ptr->next;ptr->next->prev=ptr->prev;free(ptr);return pp;}ptr=ptr->next;// !!!!!!}if(ptr==L&&ptr==p){node* pp=p->next;ptr->prev->next=ptr->next;ptr->next->prev=ptr->prev;free(ptr);return pp;}
}
//删除链表L中所有数据域等于x的结点
void remove_node(List L, dataType x)
{node* ptr=L->next;while(ptr!=L){if(ptr->data==x){ptr->prev->next=ptr->next;ptr->next->prev=ptr->prev;free(ptr);}ptr=ptr->next;// !!!!!}
}
//使链表L成为一个空链表
void make_empty(List L)
{L->next=L;L->prev=L;
}
//销毁链表L
void destroy_list(List L)
{L->prev->next=NULL;node* p=L;node* tmp;while(p){tmp=p;p=p->next;free(tmp);}
}

22.符号配对:

首先将所有要判断的符号入栈(用栈实现顺序表实现顺序表时,定义的结构体中包含数组指针和top指针指向数组尾部第一个没有元素的位置)。

然后判断左括号入栈,遇到右括号分三种情况:栈顶元素为左括号;栈空,则保存下来这个右括号;栈不空,则保存下来这个左括号。

然后判断是否这个保存符号的变量是否为初始值:为初始值且栈为空则匹配成功;为初始值但是栈不空,则取栈底元素。不为初始值就只需按照上一步保存下来的符号来输出打印即可。

23.递归创建链表。

24.快速求最大最小值(分治法),类似二分法

//类似二分法
int max(int *a,int m,int n)
{int mid;if(m==n)return a[m];else{mid=(m+n)/2;int left=max(a,m,mid);int right=max(a,mid+1,n);//一半一半的分开,最后成为前后两半的两个元素相比较//一层一层选出最大的返回出来然后比较//最里层只有一个数,把两个最里层的数返回比较if(left<right){return right;}else{return left;}}
}
int min(int *a,int m,int n)
{int mid;if(m==n)return a[m];else{mid=(m+n)/2;int left=min(a,m,mid);int right=min(a,mid+1,n);//一半一半的分开,最后成为前后两半的两个元素相比较//一层一层选出最大的返回出来然后比较//最里层只有一个数,把两个最里层的数返回比较if(left<right){return left;}else{return right;}}
}

25.n皇后问题

#include <stdio.h>
#include <stdlib.h>
#define N 20                    //最多皇后个数
int q[N];                        //存放各皇后所在的列号,即(i,q[i])为一个皇后位置void dispasolution(int n)        //输出n皇后问题的一个解
{for (int i=1;i<=n;i++)printf("(%d,%d)",i,q[i]);printf("\n");
}bool place(int i,int j)            //测试(i,j)位置能否摆放皇后
{if (i==1) return true;        //第一个皇后总是可以放置int k=1;while (k<i)            //k=1~i-1是已放置了皇后的行{    if ((q[k]==j) || (abs(q[k]-j)==abs(i-k)))return false;k++;}return true;
}
void queen(int i,int n);int main()
{    int n;                    //n为存放实际皇后个数scanf("%d",&n);if (n<=20)queen(1,n);                //放置1~i的皇后return 0;
}
void queen(int i,int n)
{if(i>n)//放置完了n个皇后{dispasolution(n);return;}else{for(int j=1;j<=n;j++)//在每一个i行试探每一个j列{if(place(i,j)){q[i]=j;//表示这个位置可行queen(i+1,n);//下一行即下一个皇后//假如j列不可以,就返回到这里,然后进行下一次for循环,试探j+1列是否可行}}}
}

26.求逆序数,用二路归并法(一边排序一边找)。

#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<malloc.h>
#define N 1000
using namespace std;
int ans=0;void Merge(int a[],int low,int mid,int high);
void mergesort(int a[],int low,int high);int main()
{int a[N],n;cin>>n;for(int i=0;i<n;i++)cin>>a[i];mergesort(a,0,n-1);cout<<ans;return 0;}void Merge(int a[],int low,int mid,int high)
{int lindex=low,rindex=mid+1;int team[high-low+1];int teamindex=0;while(lindex<=mid&&rindex<=high)//这里注意每部分的截止条件{if(a[lindex]<=a[rindex]){team[teamindex++]=a[lindex++];}else{team[teamindex++]=a[rindex++];//ans++;//不对ans+=mid-lindex+1;//加上左侧还剩余的//为什么只有这个else条件需要加呢//因为前提是你这两部分已经是有序的了,当lindex<rindex时,//在左边那部分中lindex小于左边所有的数据,而lindex小于rindex,即小于右边所有的元素,//所以把他前移不会影响逆序数的数量,因为对lindex来说不存在逆序数//但当rindex小于lindex时,rindex小于左边所有的元素(小于左边存在逆序数),//也小于右边所有的元素(小于右边不存在逆序数)//所以改变的逆序数的数量即为左边所有元素的数量}}//这两个while循环最后只执行一个,因为只有一个走到头了才会结束上面那个循环while(lindex<=mid){team[teamindex++]=a[lindex++];}while(rindex<=high){team[teamindex++]=a[rindex++];}for(int i=0;i<teamindex;i++){a[low+i]=team[i];//注意a的下标从哪里开始,因为是一层一层的}
}
void mergesort(int a[],int low,int high)
{if(low<high){int mid=(low+high)/2;//这个函数调用顺序是最先两个元素比较排序,在排序的过程中判断有没有逆序数mergesort(a,low,mid);mergesort(a,mid+1,high);Merge(a,low,mid,high);}
}

27.输出全排列(不重复)

eg:3---123、132、213、231、312、321


#include <stdio.h>
int a[15]= {0};
int books[15]= {0}; //用来记录这个数字出现没有
void Print(int a[],int n)
{for(int i=1; i<=n; i++){printf("%d",a[i]);}printf("\n");
}
void go(int a[],int n,int step)
{if(step>n){Print(a,n);return;}else{for(int i=1; i<=n; i++){if(books[i]==0){books[i]=1;a[step]=i;go(a,n,step+1);a[step]=0;//step=i这一步试探结束,再往前(step-1)回溯了books[i]=0;}}}
}
int main()
{int n;scanf("%d",&n);go(a,n,1);
}

28.整数分解。


#include <stdio.h>
int n;
int a[40];
int cnt=0;
void dfs(int num,int location,int sum)//第一个参数为当前因子的大小
{//上一层传进来的是location+1,相当于已经多了一位了,所以循环的时候i<locationif(sum==n){for(int i=1; i<location; i++){if(i==1)printf("%d=%d",n,a[i]);elseprintf("+%d",a[i]);}cnt++;if(cnt%4==0||num==n)//第二个条件表明当只有一个因子时输出回车printf("\n");else if(cnt%4!=0)printf(";");}else if(sum<n){for(int j=num; j<=n; j++){a[location]=j;dfs(j,location+1,sum+j);//第一个参数得是ja[location]=0;}}else//需要有退出的条件,不能只有上面两个判断条件//否则卡在第一次调用中无法回溯return;
}
int main()
{scanf("%d",&n);dfs(1,1,0);
}

29.求最大子段和。

中心思想就是规避负数。

30.求解简单装载问题(回溯法)
//剪枝
//对于第i层的某个分枝结点,对应的调用状态是dfs (num, tw, rw, op,i) ,对应的扩展结点有2个:
//左分支:
//          ●选择第i个
//          ➢op[i]=1 , num=num+1, tw=tw+w[i], rw=rw-w[i],转到下一个状态dfs(num, tw, rw,op,i+1)
//右分支:
//          ●不选择第i个,
//          ➢op[i]=0, num不变, tw不变, rw=rw-w[i] ,转到下一 个状态dfs (num, tw, rw, op,i+1)
//默认选择左分支,到这一层发现超出重量了,便回溯到上一个节点,选择右分支,既不选择这个点
//选择过程呈现为一棵倒立的二叉树

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define MAXN 20                        //最多集装箱个数
//问题表示
int w[MAXN]={0};                //各集装箱重量,不用下标0的元素
int    n,W;
int maxw;                            //存放最优解的总重量
int x[MAXN];                        //存放最优解向量
int minnum=999999;                    //存放最优解的集装箱个数,初值为最大值
void dfs(int num,int tw,int rw,int op[],int i);
void dispasolution(int n)        //输出一个解
{for (int i=1;i<=n;i++)if (x[i]==1)printf("%d ",i);
}
int main()
{int i;cin>>n>>W;for(int i=1;i<=n;i++)cin>>w[i];int op[MAXN];                //存放临时解memset(op,0,sizeof(op));int rw=0;for (int i=1;i<=n;i++)rw+=w[i];dfs(0,0,rw,op,1);dispasolution(n);return 0;
}
//其中num表示选择的集装箱个数,tw表示选择的集装箱重量和,
//rw表示剩余集装箱的重量和,
//op表示一个解,即一个选择方案,i表示考虑的集装箱i。
void dfs(int num,int tw,int rw,int op[],int i)
{if(i>n)//i从1开始{if(tw==W&&num<minnum){minnum=num;for(int j=1;j<=n;j++){x[j]=op[j];}}}else{op[i]=1;if(tw+w[i]<=W)//只有重量没超才会继续向下递归,这就是边界条件{dfs(num+1,tw+w[i],rw-w[i],op,i+1);}//下面是另一个分支//两个分支一定都要走一遍,所以这样并行排列op[i]=0;if(tw<=W){dfs(num,tw,rw,op,i+1);//注意是rw-w[i],因为舍弃了这一个集装箱了//传rw也可以,没有影响}}
}

31.0/1背包问题(回溯法)要求价值最大

#include <stdio.h>
#include <string.h>
#include <iostream>
#define MAXN 20                //最多物品数
using namespace std;
int n;                        //物品数
int W;                        //限制重量
int w[MAXN]={0};            //存放物品重量,不用下标0元素
int v[MAXN]={0};            //存放物品价值,不用下标0元素
int x[MAXN];                    //存放最终解
int maxv;                         //存放最优解的总价值
void dfs(int i,int tw,int tv,int rw,int op[]);
void dispasolution()            //输出最优解
{    int i;for (i=1;i<=n;i++)if (x[i]==1)printf("%d ",i);printf("\n%d %d",W,maxv);
}
int main()
{int i;cin>>n>>W; //输入物体个数及背包载重量for(int i=1;i<=n;i++)//输入各物体重量及价值cin>>w[i]>>v[i];int op[MAXN];                //存放临时解memset(op,0,sizeof(op));int rw=0;for (int i=1;i<=n;i++)rw+=w[i];dfs(1,0,0,rw,op);dispasolution();return 0;
}
//就按照这个if和else分析
//注意else中的写法
void dfs(int i,int tw,int tv,int rw,int op[])
{if(i>n){if(tw==W&&tv>maxv){//   W=tw;maxv=tv;for(int i=1;i<=n;i++){x[i]=op[i];}}}else{op[i]=1;if(tw+w[i]<=W){dfs(i+1,tw+w[i],tv+v[i],rw-w[i],op);}op[i]=0;if(tw<=W){dfs(i+1,tw,tv,rw,op);}}
}

32.循环队列操作集。

typedef struct _queue
{int front;//队头指针int rear;//队尾指针int *data;//指向数据区
}queue;
#include <malloc.h>
//创建一个空队列
int capacity=MAXSIZE;
queue* createQueue()
{queue* Queue;//这个地方切记要给这个指针开辟空间Queue=(queue*)malloc(sizeof(queue));Queue->data=(int*)malloc(capacity*sizeof(int));if(!Queue->data)exit(-1);Queue->front=Queue->rear=0;return Queue;
}
//入队
void enQueue(queue* q, int x)
{//注意这是循环链表,不用多开辟空间if(q->rear==capacity){//capacity*=2;//q->data=(int*)realloc(q->data,sizeof(int)*capacity);//if(!q->data)//exit(-1);q->rear=0;}q->data[q->rear++]=x;
}
//判断队列是否已满
bool isFull(queue* q)
{//注意循环链表,rear可能小于front//因为循环链表不好判断队满还是队空,因为都是rear=front//所以规定满的情况是rear后面的那一块空间不存储,再下一块空间才是frontif((q->rear+1)%capacity==q->front)return true;elsereturn false;
}
//出队
void deQueue(queue* q)
{if(!isEmpty(q))q->front++;
}
//得到队头元素的值
int front(queue* q)
{return q->data[q->front];
}
//判断队列是否为空
bool isEmpty(queue* q)
{if(q->front==q->rear)return true;elsereturn false;
}
//返回队列长度
int size(queue* q)
{//注意判断方式//把下面这两种情况结合起来//rear-front//rear-front+capacityreturn (q->rear-q->front+capacity)%capacity;
}
//销毁队列
void destroyQueue(queue* q)
{if(!q->data)return;free(q->data);q->data=NULL;q->front=q->rear=0;
}

33.双端队列操作。

头指针指向的有元素,先移动再赋值。

尾指针指向的是空的空间,先赋值再移动。

typedef int Position; /* 整型下标,表示元素的位置 */
typedef struct DequeNode *Deque;
struct DequeNode {int capacity;     /* 双端队列的容量 */Position front;   /* 双端队列的队首指针,初始化为0 */Position rear;    /* 双端队列的队尾指针,初始化为0 */QElemSet *data;   /* 存储数据的数组 */
};
void InitDeque(Deque deque, int n)
{   /* 注意:为区分空队列和满队列,需要多开辟一个空间 */deque->data = (QElemSet *)malloc(sizeof(QElemSet) * (n+1));deque->front = deque->rear = 0;deque->capacity = n+1;
}//是循环存的,前面插入元素在开头的话,那么下一个头插的就要插在尾部
//这两个指针指向的位置都是空的,就是说插入这个位置,指针再移动即可
//头插
bool EnQueue(Deque deque, QElemSet x)
{if((deque->rear+1)%(deque->capacity)==deque->front)return false;else{//保证循环起来deque->front=((deque->front-1)+deque->capacity)%deque->capacity;deque->data[deque->front]=x;return true;}
}
//头删
QElemSet DeQueue(Deque deque)
{if(deque->front==deque->rear)return ERROR;else{QElemSet q=deque->data[deque->front];deque->front=(deque->front+1+deque->capacity)%deque->capacity;return q;}
}
//尾插
bool Inject(Deque deque, QElemSet x)
{if((deque->rear+1)%deque->capacity==deque->front){return false;}else{deque->data[deque->rear]=x;deque->rear=(deque->rear+1)%deque->capacity;return true;}
}
//尾删
QElemSet Eject(Deque deque)
{if(deque->front==deque->rear)return ERROR;//单独分析这种情况,因为0再减一就是-1,数组越界了if(deque->rear==0){deque->rear=deque->capacity;//这样的话下面再减一正好是最后一位元素}QElemSet q=deque->data[--deque->rear];return q;
}

34.先序创建 统计二叉树中具有度为1的结点数目

创建二叉树时记得创建的是每一个节点,和链表不同,这个是通过递归把左右子树的节点地址保存在该节点中实现的。


//头文件包含
#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#include <string>
#include <iostream>
using namespace std;
//函数状态码定义
#define TRUE       1
#define FALSE      0
#define OK         1
#define ERROR      0
#define OVERFLOW   -1
#define INFEASIBLE -2
#define NULL  0
typedef int Status;//二叉链表存储结构定义
typedef char TElemType;
typedef struct BiTNode{TElemType data;struct BiTNode  *lchild, *rchild;
} BiTNode, *BiTree;//创建二叉树各结点,输入零代表创建空树
//采用递归的思想创建
//递归边界:空树如何创建呢:直接输入0;
//递归关系:非空树的创建问题,可以归结为先创建根节点,输入其数据域值;再创建左子树;最后创建右子树。左右子树递归即可完成创建!
int i=0;
Status CreateBiTree(BiTree &T,string s)
{TElemType e;if(!s[i])return OK;if(s[i]=='*'){T=NULL;i++;}else{T=(BiTree)malloc(sizeof(BiTNode));if(!T)exit(OVERFLOW);T->data=s[i++];CreateBiTree(T->lchild,s);CreateBiTree(T->rchild,s);}return OK;
}
int PreOrder(BiTNode* root)
{if(!root)return 0;else{//看清题目中让求的是度为1的,所以这样写
//        return 1+PreOrder(root->lchild)+PreOrder(root->rchild);if((!root->lchild&&root->rchild)||(root->lchild&&!root->rchild))return 1+PreOrder(root->lchild)+PreOrder(root->rchild);elsereturn PreOrder(root->lchild)+PreOrder(root->rchild);}}
int main() {string s;BiTree B;while(cin>>s) {if(CreateBiTree(B,s)){i=0;int num=PreOrder(B);cout<<"num: "<<num<<endl;}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/55057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TensorRT-LLM七日谈 Day4

在Day2 中&#xff0c;我们梳理了trt-llm对于TinyLLama的调用&#xff0c;在Day3,我们也熟悉了一下Trt-llm常规的三步流程。 这里其实有个问题&#xff0c;在针对tiny-llama的部署中&#xff0c;其实没有显式的进行模型转换&#xff0c;那麽其推理接口中到底包含了什么&#x…

46 C 语言文件的打开与关闭、写入与读取函数:fopen、fclose、fputc、fputs、fprintf、fgetc、fgets、fscanf

目录 1 文件的存储形式 2 打开文件——fopen() 函数 2.1 功能描述 2.2 函数原型 2.3 文件打开方式&#xff08;模式&#xff09; 3 关闭文件——fclose() 函数 3.1 功能描述 3.2 函数原型 4 常见的文件写入方式 4.1 fputc() 函数 4.1.1 功能描述 4.1.2 函数原型 4…

windows自动化(一)---windows关闭熄屏和屏保

电脑设置关闭屏幕和休眠时间不起作用解决方案 一共三个方面注意&#xff1a; 一、关闭屏保设置&#xff1a; 二、电源管理设置 三、关闭盖子不做操作&#xff1a; 第一点很重要&#xff0c;就算二三都做了&#xff0c;一没做&#xff0c;照样不行。

一篇python的pandas数据分析,分组与聚合使用!

在数据分析中,数据分组与聚合是常用的操作,能够帮助我们从大量数据中提取出有用的信息.我们讨论了描述性统计,了解了如何通过均值、方差等统计量概述数据的特征.而在本篇中,我们将学习如何对数据进行分组和聚合,以便进行更深入的分析.最后,我们将在后续的章节中使用这些分析结果…

PHP政务招商系统——高效连接共筑发展蓝图

政务招商系统——高效连接&#xff0c;共筑发展蓝图 &#x1f3db;️ 一、政务招商系统&#xff1a;开启智慧招商新篇章 在当今经济全球化的背景下&#xff0c;政务招商成为了推动地方经济发展的重要引擎。而政务招商系统的出现&#xff0c;更是为这一进程注入了新的活力。它…

ES(Elasticsearch)SSL集群部署

8.x后ES不在需要自行准备JDK环境&#xff0c;部署的服务包含ES、Kibana、Logstash&#xff0c;使用二进制方式部署&#xff0c;为了提高安全性&#xff0c;加密logstash、kibana及其他客户端到ES间的通信。 1、准备工作 1.1、 es无法使用root用户启动 useradd -m -s /bin/bas…

WebGl 使用uniform变量动态修改点的颜色

在WebGL中&#xff0c;uniform变量用于在顶点着色器和片元着色器之间传递全局状态信息&#xff0c;这些信息在渲染过程中不会随着顶点的变化而变化。uniform变量可以用来设置变换矩阵、光照参数、材料属性等。由于它们在整个渲染过程中共享&#xff0c;因此可以被所有使用该着色…

【C#网络编程】基础概念2

文章目录 网络、数据包和协议网络数据包协议TCP、UDP 地址客户端和服务器套接字 网络、数据包和协议 计算机网络通过通信通道互连的机器组成&#xff0c;通常把这些机器称为主机和路由器&#xff0c;主机是是运行应用程序&#xff08;如 Web 浏览器&#xff09;的计算机。路由器…

决战Linux操作系统

前言&#xff1a; 你是否也曾经为Linux所困扰过&#xff0c;在网上找的资料零零散散&#xff0c;是否学完Linux后还是懵懵懂懂&#xff0c;别怕&#xff0c;这篇博客是博主精心为你准备的&#xff0c;现在&#xff0c;就让我们一起来走进Linux的世界&#xff0c;决战Linux&…

一文详解数据库范式

背景 在开发中&#xff0c;我们经常需要考虑如何设计合适的表结构&#xff0c;而则往往需要考虑数据库的范式。数据库的三范式&#xff08;3NF&#xff09;是数据库设计过程中用来减少数据冗余和提高数据一致性的重要规则。它们分别是第一范式&#xff08;1NF&#xff09;、第二…

oracle数据坏块处理(一)-通过rman备份修复

表有坏块时&#xff0c;全表查询会报错&#xff1a; 这时候如果有前面正常的rman备份&#xff0c;那么我们就可以通过rman备份直接对数据文件块做恢复 先对数据文件做个逻辑检查&#xff1a; RMAN> backup check logical VALIDATE DATAFILE EXB_DATA/exb/datafile/cuteinf…

C#中Assembly3个获取路径的方法

在C#中&#xff0c;经常要获取路径 &#xff0c;可以通过Assembly的三个重载方法来获取&#xff0c;如下所示这三个分别是GetCallingAssembly、GetEntryAssembly和GetExecutingAssembly。 string tmpEntryPath Assembly.GetEntryAssembly().Location;string tmpExeasmPath As…

STM32CubeIDE使用ADC采用DMA重大BUG

问题描述 STM32CubeIDE 1.8.0问题 大牛攻城狮最近调试STM32L151CBT6。由于项目上使用该款芯片做控制电源使用&#xff0c;其中涉及到多路ADC的数据采样。使用STM32CubeIDE 1.8.0版本详细如下图所示 这里大概率是STM32CubeMX版本太低了&#xff0c;从图上看才是6.4.0 注意这里…

五、UI弹窗提示

一、制作弹窗UI 二、创建脚本 1、继承WindowRoot&#xff08;UI基类&#xff09; 获取UI上面的组件 2、初始化 将这个文本失活 3、写一个提示出现的方法 这个派生类中&#xff0c;继承了基类的两个方法&#xff0c;设置显示和设置文本 对应基类的这两个方法 将动画赋值给动…

25.1 降低采集资源消耗的收益和无用监控指标的判定依据

本节重点介绍 : 降低采集资源消耗的收益哪些是无用指标&#xff0c;什么判定依据 通过 grafana的 mysql 表获取所有的 查询表达式expr通过 获取所有的prometheus rule文件获取所有的 告警表达式expr通过 获取所有的prometheus 采集器接口 获取所有的采集metrics计算可得到现在…

机器学习、深度学习评价指标汇总:TP、TN、FP、FN、AP、mAP、IoU、mAP@3、Prec@10、 Acc@10

系列文章目录 文章目录 系列文章目录一、真正例&#xff08;True Positive&#xff09;、假正例&#xff08;False Positive&#xff09;、真负例&#xff08;True Negative&#xff09;和假负例&#xff08;False Negative&#xff09;是评估分类模型性能的重要概念。1. 定义2…

前端学习-css的元素显示模式(十五)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 什么是元素显示模式 块元素 常见的块元素 块元素的特点 注意 行内元素 行内元素的特点 注意 行内块元素 行内块元素的特点 元素显示模式的转换 语法格…

MySQL 删除数据库

1.使用命令行删除一个数据库 1.1 首先登陆进入 MySQL 操作界面&#xff0c;命令如下&#xff1a; 命令 : mysql -utest -p;1.2 登陆成功之后可以使用如下命令查看当前已有数据库&#xff1a; 命令 : SHOW DATABASES; 执行结果如下图: 如图所示当前已包含 MySQL 系统数据库和…

盛元广通化学实验室样品LIMS管理系统

盛元广通化学实验室样品LIMS管理系统旨在提高实验室样品管理的效率、准确性和可追溯性。通过自动化和智能化的手段&#xff0c;系统能够简化样品管理流程&#xff0c;减少人为错误&#xff0c;确保样品的安全性和完整性。样品管理的具体实施方法包括样品接收与登记、样品储存与…

「Ubuntu」文件权限说明(drwxr-xr-x)

我们在使用Ubuntu 查看文件信息时&#xff0c;常常使用 ll 命令查看&#xff0c;但是输出的详细信息有些复杂&#xff0c;特别是 类似与 drwxr-xr-x 的字符串&#xff0c;在此进行详细解释下 属主&#xff1a;所属用户 属组&#xff1a;文件所属组别 drwxr-xr-x 7 apps root 4…