搜索二叉树 stackoverflow

R-I-P 2012-12-28 12:50:45
struct.h

#ifndef _struct_H
#define _struct_H
typedef struct Road_info {
unsigned short data_size; //数据大小 2byte
unsigned int LinkID; //道路编号 4byte
unsigned short road_size; //道路名称的尺寸 2byte
//以下是NODE中的数据 4byte
unsigned int linkid; //番号 3-0
unsigned int brunch; //分岔路 6-4
unsigned int roadnameflag; //路标 7
char *roadname; //道路名称
}Road_info;

typedef struct Road{
struct Road_info stRoadRec; //节点数据
struct Road* next; //下一节点
}Road;

#endif



Map_Tree.h


#include<string.h>
#include "struct.h"




typedef struct Map_Tree{
struct Map_Tree *left;
struct Map_Tree *right;
unsigned int data;
}*Map_tree;

Map_tree CreatTree_byLinkId( Road *head, int position); //使用递归建立二叉树 Linkid部分
Map_tree HalfSearch_byLinkId(Map_tree point, int findnode); //二叉树二分查找方式

void show_byLinkd(Road *head);


Map_Tree.c

#include"Map_Tree.h"

void show_byLinkd(Road *head)
{
Map_tree root=NULL;
Map_tree point=NULL;
time_t a,b;
char Run_time[80];
unsigned int findnode;
Road *temp;


root=CreatTree_byLinkId(head,1);
printf("请输入您所想要查询的LinkId:\n");
scanf("%d",&findnode);

a=time(NULL);
strftime(Run_time,79,"%H:%M:%S",localtime(&a));


point=HalfSearch_byLinkId(root,findnode);//用二分法查找二叉树
if(point!=NULL){
printf("#linkid=%d\n",head->stRoadRec.LinkID);
printf("roadnameflag=%d\n",head->stRoadRec.roadnameflag);
printf("brunch=%d\n",head->stRoadRec.brunch);
printf("dispclass=%d\n",head->stRoadRec.linkid);
printf("roadname=%s#\n",head->stRoadRec.roadname);
temp->stRoadRec.LinkID=head->stRoadRec.LinkID;
temp->stRoadRec.roadnameflag=head->stRoadRec.roadnameflag;
temp->stRoadRec.brunch=head->stRoadRec.brunch;
temp->stRoadRec.linkid=head->stRoadRec.linkid;
temp->stRoadRec.roadname = head->stRoadRec.roadname;
}
else
printf("error:未找到结果!!\n");

b=time(NULL);
strftime(Run_time,79,"%H:%M:%S",localtime(&b));

printf("本次查找用时%d 秒.\n",b-a);

}

Map_tree CreatTree_byLinkId(Road *head, int position)
{
Map_tree newnode; //声明新节点指针

if(head->next==NULL) //递归的终止条件
return NULL;
else{
//建立新节点的内存空间
newnode = (Map_tree) malloc(sizeof(Road));

//建立节点内容
newnode->data =head->stRoadRec.LinkID;
//递归建立左子树
newnode->left = CreatTree_byLinkId(head, 2*position);
//递归建立右子树
newnode->right = CreatTree_byLinkId(head, 2*position+1);
return newnode; //返回树的位置
}
}

Map_tree HalfSearch_byLinkId(Map_tree point, int findnode)
{
while(point!=NULL)
{
if(point->data==findnode)
return point;//找到了该结点
else
if(point->data>findnode)
point=point->left;
else
point=point->right;
}
return NULL;
}


在建立树的时候 stackoverflow了 一共有6万多条数据,链表
现在不知道怎么解决,对 stack 不是很理解
应该怎么办??
...全文
305 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2012-12-28
  • 打赏
  • 举报
回复
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门! 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出
R-I-P 2012-12-28
  • 打赏
  • 举报
回复
引用 7 楼 tianweishuiguo 的回复:
C/C++ code?123 if(head->next==NULL) //递归的终止条件 return NULL;//将终止条件改一下,比如newnode->data == ""; return;
但是递归里的参数是head 依旧会死循环啊
东大坡居士 2012-12-28
  • 打赏
  • 举报
回复

 if(head->next==NULL) //递归的终止条件
  return NULL;
//将终止条件改一下,比如newnode->data == ""; return;
R-I-P 2012-12-28
  • 打赏
  • 举报
回复
引用 5 楼 tianweishuiguo 的回复:
C/C++ code?1234567891011121314151617181920Map_tree CreatTree_byLinkId(Road *head){ Map_tree newnode; //声明新节点指针 if(head->next==NULL) //递归的终止条件 return NULL; else{ //建立新节点的内存空间 ne……
那要怎么改呢?才不会出现死循环
东大坡居士 2012-12-28
  • 打赏
  • 举报
回复

Map_tree CreatTree_byLinkId(Road *head){
 Map_tree newnode;       //声明新节点指针
 
 if(head->next==NULL) //递归的终止条件
  return NULL;
 else{
  //建立新节点的内存空间
  newnode = (Map_tree) malloc(sizeof(Road));
 
  //建立节点内容
  newnode->data =head->stRoadRec.LinkID;
  //递归建立左子树
  //head=head->next;
  newnode->left = CreatTree_byLinkId(head);//....
  //递归建立右子树
  //head=head->next;
  newnode->right = CreatTree_byLinkId(head);//你这个递归传递的参数都是head, 也是死循环
  return newnode;       //返回树的位置
 }
}
R-I-P 2012-12-28
  • 打赏
  • 举报
回复
晕~ 发错代码了

#include"Map_Tree.h"

void show_byLinkd(Road *head)
{
	Map_tree root=NULL;
	Map_tree point=NULL;
	time_t a,b;
    char Run_time[80];
	int findnode;


	root=CreatTree_byLinkId(head);
	printf("请输入您所想要查询的LinkId:\n");
	scanf("%d",&findnode);

	a=time(NULL);
	strftime(Run_time,79,"%H:%M:%S",localtime(&a));


	point=HalfSearch_byLinkId(root,findnode);//用二分法查找二叉树
	if(point!=NULL){
		printf("#linkid=%d ",head->stRoadRec.LinkID);
		printf("roadnameflag=%d ",head->stRoadRec.roadnameflag);
		printf("brunch=%d ",head->stRoadRec.brunch);
		printf("dispclass=%d ",head->stRoadRec.linkid);
		printf("roadname=%s# \n",head->stRoadRec.roadname);
	}
	else
		printf("error:未找到结果!!\n");

	b=time(NULL);
	strftime(Run_time,79,"%H:%M:%S",localtime(&b));

	printf("本次查找用时%d 秒.\n",b-a); 

}

Map_tree CreatTree_byLinkId(Road *head){
 Map_tree newnode;       //声明新节点指针

 if(head->next==NULL) //递归的终止条件
  return NULL;
 else{
  //建立新节点的内存空间
  newnode = (Map_tree) malloc(sizeof(Road));

  //建立节点内容
  newnode->data =head->stRoadRec.LinkID;
  //递归建立左子树
  //head=head->next;
  newnode->left = CreatTree_byLinkId(head);
  //递归建立右子树
  //head=head->next;
  newnode->right = CreatTree_byLinkId(head);
  return newnode;       //返回树的位置
 }
}

Map_tree HalfSearch_byLinkId(Map_tree point, int findnode)
{
	while(point!=NULL)
	{
		if(point->data==findnode)
			return point;//找到了该结点
		else
			if(point->data>findnode)
				point=point->left;
			else
				point=point->right;
	}
	return NULL;
}
这个才是Map_Tree.c
whizer 2012-12-28
  • 打赏
  • 举报
回复
递归函数需要一个退出条件.
科比布莱恩特 2012-12-28
  • 打赏
  • 举报
回复
死循环
rocktyt 2012-12-28
  • 打赏
  • 举报
回复
CreatTree_byLinkId里面的head,从头到尾就没变过,死循环啊
proorck6 2012-12-28
  • 打赏
  • 举报
回复
引用 3 楼 whizer 的回复:
递归函数需要一个退出条件.
++
R-I-P 2012-12-28
  • 打赏
  • 举报
回复
引用 12 楼 Ksly_Tkol 的回复:
C/C++ code?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990#incl……
我是将单向有序链表传入,应该有很大的不同
  • 打赏
  • 举报
回复
#include<stdio.h>
#include<malloc.h>

#define FALSE 1
#define ERROR 0
#define OK 1
#define ON 0

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

typedef int Status;
BiTree T;

Status CreateBiTree(BiTree *T)
{
    char ch;
    scanf("%c",&ch);
    if (ch==' ')
        *T = NULL;
    else
    {
        if (!((*T) = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;
        (*T)->data = ch;
        CreateBiTree(&((*T)->lchild));   // 构造左子树
        CreateBiTree(&((*T)->rchild));   // 构造右子树
    }
    return OK;
} // CreateBiTree

int vi(char c)
{
    printf("%c ",c);
    return OK;
}

//先序遍历的递归
void PreOrder(BiTree T)
{
    if(T)
    {
        vi(T->data);      //访问结点
        PreOrder(T->lchild);       //遍历左子树
        PreOrder(T->rchild);       //遍历右子树
    }
}

//中序遍历的递归
void InOrder(BiTree T)
{
    // 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。
    // 中序遍历二叉树T的递归算法,对每个数据元素调用函数Visit。
    if(T)
    {
    InOrder(T->lchild);
    vi(T->data);
    InOrder(T->rchild);
    }
} // InOrderTraverse

//后序遍历的递归
void PostOrder(BiTree T)
{
    // 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。
    // 中序遍历二叉树T的递归算法,对每个数据元素调用函数Visit。
    if(T)
    {
    PostOrder(T->lchild);
    PostOrder(T->rchild);
    vi(T->data);
    }
} // InOrderTraverse
int main()
{
    printf("先序输入二叉树(空格代表空节点):\n");
    CreateBiTree(&T);
    printf("先序输出二叉树:\n");
    PreOrder(T);
    printf("\n");
    printf("中序输出二叉树:\n");
    InOrder(T);
    printf("\n");
    printf("后序输出二叉树:\n");
    PostOrder(T);
    printf("\n");
    return 0;
}
这是我写的,你可以看一下
R-I-P 2012-12-28
  • 打赏
  • 举报
回复
引用 10 楼 logiciel 的回复:
试改如下 C/C++ code?123456789101112131415161718192021222324252627282930Map_tree AddTree(Map_tree node, int LinkID){ if (node == NULL) { node = (Map_tree) malloc(sizeof(Road)); node->……
能说一下 函数 接受的参数么? LinkID是什么意思
logiciel 2012-12-28
  • 打赏
  • 举报
回复
试改如下
Map_tree AddTree(Map_tree node, int LinkID)
{
  if (node == NULL)
  {
    node = (Map_tree) malloc(sizeof(Road));
    node->data = LinkID;
    node->left = node->right = NULL;
  }
  else if (node->data <= LinkID)
  {
    node->left = AddTree(node->left, LinkID);
  }
  else
  {
    node->right = AddTree(node->right, LinkID);
  }
  return node;
}

Map_tree CreatTree_byLinkId(Road *head)
{
  Map_tree root = NULL;
  Road *p = head;
  while (p)
  {
    root = AddTree(root, p->stRoadRec.LinkID);
    p = p->next;
  }
  return root;
}
1. IO:(Input Output)是输入输出流 从内存到硬盘就是输出流Output 从硬盘到内存就是输入流Input IO操作的最基础的是文件File 2. File 1. 概念:就是java中的一个文件或者文件夹。如果没有后缀就表示是一个文件夹,如果有后缀就表示文件。 2. 作用:为了IO流提供操作的基础 3. 使用: 1. 常量: 1.1. static String pathSeparator 与系统相关的路径分隔符字符,为方便起见,表示为字符串。 1.2. static String separator 2. 构造方法: 2.1 File(String pathname) 根据文件名创建一个File对象, pathname:(如果有后缀就是一个文件对象,如果没有后缀会默认为是一个文件夹对象) 1. 相对路径:相对于当前Java类的项目 2. 绝对路径:从根目录或者盘符开始 /都表示从根目录或者盘符开始 2.2 File(String parent, String child) 在父级目录下创建一个文件或文件夹 parent:父级目录 child:当前目录或者当前文件 2.3 File(File parent, String child) 在父级目录下创建一个文件或文件夹 3. 常用方法: 常用方法:获取子文件夹或者子文件方法 * 1.String[] list()获取当前文件夹下所有的子文件夹或者子文件的名 //文件没有下一级 2.File[] listFiles() 获取当前文件夹下所有的子文件夹或者子文件对象 ===================================有过滤功能=================================== * 3.String[] list(FilenameFilter filter) 获取根据文件名过滤后的文件名 FilenameFilter:文件名过滤器接口 4.File[] listFiles(FilenameFilter filter) 获取根据文件名过滤后的文件对象 FilenameFilter:文件名过滤器接口 -----------------------------上面只能根据文件名或者文件夹名过滤,下面的可以通过文件的其他属性过滤,例如:文件大小等----------------------------- 5.File[] listFiles(FileFilter filter) 获取根据文件过滤后的文件对象 FileFilter:文件过滤器接口 2. 递归: 1. 概念:是一种思想,也是一种算法。在方法内部调用自己的方法。(自己干自己) 2. 作用:就是简化有相似的业务逻辑(循环)代码。 3. 使用规律特点: 1. 通过数值带入的方式,查找逻辑规律: 将所有的已知条件写出来 就是有相似运算逻辑的代码 2. 通过条件判断(条件/循环)的方式,在满足条件的时候根据规律调用自己的方法。 如果不满足就不会自己的方法,这就是出口 4. 使用场景: 1. 树状结构数据、菜单结构、上下级关系等的数据查询 2. 有相似逻辑运算的结构 3. 适用于层级结构少,数据量小的场景。(最重要)如果层级多,且数据量大用循环。 5. 解决了哪些问题: (1)数据的定义是按递归定义的。(Fibonacci函数:斐波拉契数列) (2)问题解法按递归算法实现。(汉诺塔问题) 这类问题虽则本身没有明显的递归结构,但用递归求解比迭代求解更简单,如Hanoi问题。 (3)数据的结构形式是按递归定义的。 如二叉树、广义表等,由于结构本身固有的递归特性,则它们的操作可递归地描述。 6. 注意事项: 1. 递归必须 有出口 2. 能用循环用循环,不要用递归,因为效率极其低下。 为什么效率低下? 方法的调用都是创建新栈帧,入栈,而栈层级是有限制的 StackOverflowError : 栈内存溢出错误。

69,368

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧