求一个一维数组的最大元素和最小元素的位置
我设计的思路也比较简单
#include<stdio.h>
int maxstr(int *a)
{
int i,max=a[0],t;
for(i=1;i<10;i++)
{
if(max<a[i])
{
max=a[i];
t=i; }
}
return t+1;
}
int minstr(int *a)
{
int i,min=a[0],t;
for(i=1;i<10;i++)
{
if(min>a[i])
{
min=a[i];
t=i;
}
}
return t+1;
}
void main()
{
int a[10],i,max,min;
printf("请输入一组(10个为一组)一维数组:");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
max=maxstr(a);
min=minstr(a);
printf("最大元素的位置:%d\n最小元素的位置:%d",max,min);
}
为什么输出的两个位置会一样呢
给t赋初始值:
#include<stdio.h>
int maxstr(int *a)
{
int i,max=a[0],t=0; //修改的地方
for(i=1;i<10;i++)
{
if(max<a[i])
{
max=a[i];
t=i;
}
}
return t+1;
}
int minstr(int *a)
{
int i,min=a[0],t=0;//修改的地方
for(i=1;i<10;i++)
{
if(min>a[i])
{
min=a[i];
t=i;
}
}
return t+1;
}
int main()
{
int a[10],i,max,min;
printf("请输入一组(10个为一组)一维数组:");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
max=maxstr(a);
min=minstr(a);
printf("最大元素的位置:%d\n最小元素的位置:%d",max,min);
}
两个函数里,t 都没有初始化,t 应该初始化为 t = 0;
供参考:
#include<stdio.h>
int maxstr(int* a)
{
int i, max = a[0], t = 0; // 修改
for (i = 1; i < 10; i++)
{
if (max < a[i])
{
max = a[i];
t = i;
}
}
return t + 1;
}
int minstr(int* a)
{
int i, min = a[0], t = 0; // 修改
for (i = 1; i < 10; i++)
{
if (min > a[i])
{
min = a[i];
t = i;
}
}
return t + 1;
}
void main()
{
int a[10], i, max, min;
printf("请输入一组(10个为一组)一维数组:");
for (i = 0; i < 10; i++)
scanf("%d", &a[i]);
max = maxstr(a);
min = minstr(a);
printf("最大元素的位置:%d\n最小元素的位置:%d", max, min);
}
int i,max=a[0],t;
int i,min=a[0],t;
->
int i,max=a[0],t=0;
int i,min=a[0],t=0;
这是我一开始写的版本:
//根据二叉树的前序遍历字符串,构建树,并输出中序遍历结果
#include <bits/stdc++.h>
using namespace std;
string s;
int len;
//定义二叉树的节点
struct node
{
char c;
node *left;
node *right;
};
void createTree(node *root)
{
if (len >= s.length())
return; //到最后一个字符了,结束返回(字符串最后3个字符一定是###)
char c = s[len++];
if (c == '#')
{
root = NULL;
return;
}
else
{
root = new node;
root->c = c;
//左右孩子初始化
root->left = NULL;
root->right = NULL;
//因为字符串s是线序遍历,所以这里根据先序遍历的顺序构造树
createTree(root->left);
createTree(root->right);
}
}
void midOrdTrave(node *node)
{
//中序遍历
if (node != NULL)
{
midOrdTrave(node->left);
cout << node->c << " ";
midOrdTrave(node->right);
}
return;
}
int main()
{
while (cin >> s)
{
node *binaryTreeRoot=NULL;
len = 0;
createTree(binaryTreeRoot);
midOrdTrave(binaryTreeRoot);
cout << endl;
}
return 0;
}
编译时报了Segment fault,提交时报了runtime error错误
不难知道是指针访问了不该访问的内存空间了。
后来发现,是因为main函数中,binaryTreeRoot在经历了createTree之后,仍然是NULL,这是为什么呢?
看过上面的内容,就明白了,错在createTree函数的传参。createTree函数的形参root在new node的时候便指向了一块新的内存地址了,而此时,实参binaryTreeRoot是没有任何变化的,仍然指向NULL。所以之后进行中序遍历,肯定会报错。
这个时候,我们在传参时,因为我们需要操作的是传入的实参指针,而不是形参指针,就需要把binaryTreeRoot的这个指针的地址传进去(和经典的swap例子一样的),才能起到一个真正的、数据双向绑定的效果,即:
int main()
{
while (cin >> s)
{
node *binaryTreeRoot = NULL;
len = 0;
createTree(&binaryTreeRoot);
midOrdTrave(binaryTreeRoot);
cout << endl;
}
return 0;
}
这时候,createTree接收到的参数是地址的地址,也就相当于一个二重指针,所以在定义形参时,需要做一定修改,即
//建树
void createTree(node **root)
在该函数内使用时,**root为被指向的node,*root为指向节点的指针,root为指针的地址。
我们在修改节点内容时,便应该使用(*root->c=new_char)这样的方式来更新。但直接使用会报编译错误,所以我们使用一个tmp指针来过度。
//创建一个新节点
node *tmp = new node;
tmp->c = c;
tmp->left = NULL;
tmp->right = NULL;
*root = tmp;
//因为字符串s是线序遍历,所以这里根据先序遍历的顺序构造树
createTree(&(tmp->left));
createTree(&(tmp->right));
后两行递归也是一样的道理。
那么完整的更新后的代码如下(也可以看题解,一样的):
//根据二叉树的前序遍历字符串,构建树,并输出中序遍历结果
#include <bits/stdc++.h>
using namespace std;
string s;
int len; //每次遍历到的字符串中字符的index
//定义二叉树的节点
struct node
{
char c;
node *left;
node *right;
};
//建树
void createTree(node **root)
{
if (len >= s.length())
return; //到最后一个字符了,结束返回(字符串最后3个字符一定是###)
char c = s[len++];
if (c == '#')
{
*root = NULL;
return;
}
else
{
//创建一个新节点
node *tmp = new node;
tmp->c = c;
tmp->left = NULL;
tmp->right = NULL;
*root = tmp;
//因为字符串s是线序遍历,所以这里根据先序遍历的顺序构造树
createTree(&(tmp->left));
createTree(&(tmp->right));
}
}
void midOrdTrave(node *node)
{
//中序遍历
if (node != NULL)
{
midOrdTrave(node->left);
cout << node->c << " ";
midOrdTrave(node->right);
}
return;
}
int main()
{
while (cin >> s)
{
node *binaryTreeRoot = NULL;
len = 0;
createTree(&binaryTreeRoot);
midOrdTrave(binaryTreeRoot);
cout << endl;
}
return 0;
}