| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5751 人关注过本帖, 1 人收藏
标题:这么多天了,搜索二叉树才搞定了最基础的部分(蹉跎了好些岁月,终于搞定了 ...
取消只看楼主 加入收藏
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
结帖率:95.65%
收藏(1)
已结贴  问题点数:20 回复次数:22 
这么多天了,搜索二叉树才搞定了最基础的部分(蹉跎了好些岁月,终于搞定了四种遍历)
这么多天了,搜索二叉树才搞定了最基础的部分。
 
 
程序代码:
#include <stdio.h>
#include "STree.h"
#include <stdlib.h>
#include <time.h>

int
main( void )
{
    Tree Root;
    int a[ 20 ];
    int i;

    srand( ( unsigned int )time( NULL ) );
    Root = NULL;

    for( i = 0; 20 > i; ++i )
    {
        a[ i ] = rand() % 10000;
        Insert( &Root, a[ i ] );
    }
    Print( Root );//测试用函数
    printf( "\n" );
    PostorderTraversal( Root );
    printf( "\n" );
//    PrevTraversal( Root );

for( i = 0; 20 > i; ++i ){
    printf( "\n" );
    printf( "被删除的节点为%d\n", a[ i ] );
    DeleteNode( &Root, a[ i ] );
    //PrevTraversal( Root );
    //printf( "\n" );
    //InorderTraversal( Root );
    //printf( "\n" );
    PostorderTraversal( Root );
    printf( "\n" );
    //LevelTraversal( Root );
    //printf( "\n" );
}

    return 0;
}

}


 
程序代码:
#ifndef _S_TREE_H_
#define _S_TREE_H_
#define T Tree
typedef struct T *T;

int
Insert( T *TreePP, int Value );

void
DeleteNode( T *TreeP, int Value );

T
FindMin( T TreeP );

T
FindMax( T TreeP );

T
Find( T TreeP, int value );

void
Print( T TreeP );//测试用函数,可删除。

void
PrevTraversal( T TreeP );

void
InorderTraversal( T TreeP );

void
PostorderTraversal( T TreeP );

void
LevelTraversal( T TreeP );

struct T{
    int Element;
    T Left;
    T Right;
};

#undef T
#endif


 
 
程序代码:
#include "STree.h"
#include <stdlib.h>
#include <stdio.h>
#define T Tree
enum{ OK = 0, NOT };


int
Insert( T *TreePP, int Value )
{
    T Next;
    T NewCell;

    while( NULL != ( Next = *TreePP ) )
    {
        if( Value > Next->Element )
            TreePP = &Next->Right;
        else if( Value < Next->Element )
            TreePP = &Next->Left;
        else
            return NOT;
    }

    NewCell = ( T )malloc( sizeof( struct T ) );
    if( NULL != NewCell )
    {
        NewCell->Left = NULL;
        NewCell->Right = NULL;
        NewCell->Element = Value;
        *TreePP = NewCell;
        return OK;
    }
    else
        return NOT;
}


T
FindMin( T TreeP )
{
    while( NULL != TreeP->Left )
        TreeP = TreeP->Left;

    return TreeP;
}


T
FindMax( T TreeP )
{
    while( NULL != TreeP->Right )
        TreeP = TreeP->Right;
    
    return TreeP;
}


T
Find( T TreeP, int Value )
{
    while( NULL != TreeP )
    {
        if( Value > TreeP->Element )
            TreeP = TreeP->Right;
        else if( Value < TreeP->Element )
            TreeP = TreeP->Left;
        else
            break;
    }

    return TreeP;
}


void
DeleteNode( T *TreePP, int Value )
{
    T Next;
    T Min;

    while( NULL != ( Next = *TreePP ) )
    {
        if( Value == Next->Element )
        {
            if( NULL == Next->Left || NULL == Next->Right )
                break;
            Min = FindMin( Next->Right );
            Next->Element = Min->Element;
            Value = Min->Element;
            TreePP = &Next->Right;
        }
        else if( Value > Next->Element )
            TreePP = &Next->Right;
        else if( Value < Next->Element )
            TreePP = &Next->Left;        
    }
    if( NULL != Next )
    {
        if( NULL != Next->Left )
            *TreePP = Next->Left;
        else if( NULL != Next->Right )
            *TreePP = Next->Right;
        else
            *TreePP = NULL;
        free( Next );
    }

}


void
Print( T TreeP )//测试用函数,可删除。
{
    if( NULL == TreeP )
        return;

    Print( TreeP->Left );

    Print( TreeP->Right );
    printf( "%5d ",TreeP->Element );
}


static void
Posh( T Node );

static T
Pop( void );

static int
Empty( void );

static int
Full( void );

static void
DeleteStack( void );


void
PrevTraversal( T TreeP )
{
    if( NULL == TreeP )
        return;

    Posh( TreeP );
    while( !Empty() )
    {
        TreeP = Pop();
        printf( "%5d ", TreeP->Element );
        if( NULL != TreeP->Right )
            Posh( TreeP->Right );
        if( NULL != TreeP->Left )
            Posh( TreeP->Left );
    }
    DeleteStack();
}


void
InorderTraversal( T TreeP )//中序遍历并不算我写的,因为大量参考了网上找到的代码,甚至在结果上也跟参考的代码近乎一致。
{

    while( NULL != TreeP || !Empty() )
    {
        if( NULL != TreeP )
        {
            Posh( TreeP );
            TreeP = TreeP->Left;
        }
        else
        {
            TreeP = Pop();
            printf( "%5d ", TreeP->Element );
            TreeP = TreeP->Right;
        }
    }

    DeleteStack();
}


void
PostorderTraversal( T TreeP )
{
    T Signed;

    if( NULL == TreeP )
        return;

    Posh( TreeP );
    while( !Empty() )
    {
        TreeP = Pop();

        if(  ( NULL != TreeP->Right || NULL != TreeP->Left )
                && ( Signed != TreeP->Right && Signed != TreeP->Left ) )
        {
            Posh( TreeP );
            if( NULL != TreeP->Right )
                Posh( TreeP->Right );
            if( NULL != TreeP->Left )
                Posh( TreeP->Left );
        }
        else
        {
            Signed = TreeP;
            printf( "%5d ", TreeP->Element );
        }
    }

    DeleteStack();
}


#include "d:\mylib\queue.h"
MakeQueue( T, _Tree )

void
LevelTraversal( T TreeP )
{
    if( NULL == TreeP )
        return;

    Create_Tree();
    Insert_Tree( TreeP );

    while( !Is_Empty_Tree() )
    {
        TreeP = First_Tree();
        Delete_Tree();
        printf( "%5d ", TreeP->Element );
        if( NULL != TreeP->Left )
            Insert_Tree( TreeP->Left );
        if( NULL != TreeP->Right )
            Insert_Tree( TreeP->Right );
    }
    Destroy_Tree();
}


#define INITSIZE 128
static T *Stack;
static int Top = -1;
static int CurrentSize = INITSIZE;


int
Empty( void )
{
    return -1 == Top;
}


int
Full( void )
{
    if( Top == CurrentSize - 1 )
    {
        CurrentSize += INITSIZE;
        T *Temp;
        Temp = ( T * )realloc( Stack, CurrentSize * sizeof( T ) );
        if( NULL == Temp )
        {
            CurrentSize -= INITSIZE;
            return NOT;
        }
        Stack = Temp;
        return OK;
    }
    else
        return OK;
}


void
Posh( T Node )
{
    if( NULL == Stack )
    {
        Stack = ( T * )malloc( CurrentSize * sizeof( T ) );
        if( NULL == Stack )
            exit( EXIT_FAILURE );
    }
    if( !Full() )
        Stack[ ++Top ] = Node;
}


T
Pop( void )
{
    return Stack[ Top-- ];
}


void
DeleteStack( void )
{
    free( Stack );
    Stack = NULL;
    Top = -1;
    CurrentSize = INITSIZE;
}


 
 
 
 


[此贴子已经被作者于2017-5-12 19:14编辑过]

搜索更多相关主题的帖子: color 二叉树 
2017-05-09 21:20
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 2楼 九转星河
只要普通的二叉树搞定,AVL树不是问题,伸展树是AVL树的进阶,一个搞定另一个也不是太大的问题。所以,基础很重要。

删除节点,终于搞定了。

Debug了半天,才发现原来DeleteNode函数本身没有问题,问题出在FindMin函数上,我靠。

现在已经差不多了,就剩下迭代版本的四种遍历和树的深度了。希望下周之前搞定,嗯……希望这周工作不忙,要不然完全没时间想编程。

[此贴子已经被作者于2017-5-9 23:35编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-09 23:20
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 4楼 九转星河
树的四种遍历能够多难啊,大概也就花点时间整理下思路,然后就可以开写了。

反正这周尽可能完成普通树。下周进入AVL环节。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-10 10:55
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 6楼 九转星河
删除节点我已经写出来了呀。
我自己看着还挺好。

通用性以后再说吧。

我并不是太想直接调用我完成的泛型栈和队列,我不想让彼此产生依赖关系。

我现在的想法是写一些简易版本的栈和队列函数来支持四种遍历的迭代版本。

慢慢来也是个好办法,但是我的做法是搞不懂的东西就先放着,某些时候想破头都想不到的东西,但是放一放,思路也许在某个时间点突然就冒出来了。

[此贴子已经被作者于2017-5-10 11:11编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-10 11:06
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 8楼 书生牛犊
没有,我不发博客。可以点开我的个人资料,看主题帖呀。这不就是一个统计么?
论坛我都当我的一个记录,同时也算分享一下。
因此我的代码从来不写注释,就算有注释,在发出来的时候我也会全部删掉。

我的理论是,想弄懂,自己写注释。又有几个学习编程的人不是从抄代码写注释开始的呢?

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-10 12:22
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 10楼 书生牛犊
这个啊,你看看置顶贴那个通用链表呢?

二叉树基础,弄那么复杂没有必要。
通用性的问题,那是运用部分,先缓缓。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-10 12:33
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 14楼 九转星河
嗯,好的。给我点时间。无论如何,无论有没有找到问题出在哪里,我都告诉你一声。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-10 13:10
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 14楼 九转星河
我测试了一下,我没有发现有BUG啊,删除值之后一切正常。
我进行了大概50次测试,没有问题哦。

或者你告诉我一下输入序列,我试试。

嗯……终于发现了。

程序代码:
/*545 407 58 10 86 374 90 96 312 423 458 905 732 661 572 648 757 784 936 942
删除的值为545
905 732 661 572 407 58 10 86 374 90 96 312 423 458 648 757 784 936 942
删除的值为905
936 732 661 572 407 58 10 86 374 90 96 312 423 458 648 757 784 942
删除的值为407
936 732 661 572 423 58 10 86 374 90 96 312 458 648 757 784 942
删除的值为58
936 732 661 572 423 86 10 374 90 96 312 458 648 757 784 942
删除的值为86
936 732 661 572 423 374 90 10 96 312 458 648 757 784 942
删除的值为374
936 732 661 572 423 458 648 757 784 942
删除的值为732
936 757 661 572 423 458 648 784 942
删除的值为757
936 784 661 572 423 458 648 942
删除的值为784
936 942
删除的值为423
936 942
删除的值为661
936 942
删除的值为90
936 942
删除的值为10
936 942
删除的值为96
936 942
删除的值为572
936 942
删除的值为458
936 942
删除的值为936

删除的值为312

删除的值为648

删除的值为942
*/




[此贴子已经被作者于2017-5-10 13:30编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-10 13:25
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
@九转星河

目前所找的问题是,当删除带有两个子树的节点的时候,你意图重建链接。
着一个测试我研究了好久,当删除这样的节点的时候,左子树的位置发生了变化。

顺带,中午的时候,我的DeleteNode函数被我改出了BUG,希望你看的不是有BUG的版本。

程序代码:
389 19 343 181 312 252 304 387 497 490 413 825 807 632 617 759 662 804 843 966
删除的值为389//删除389之后,19的位置后移了,并且413丢失了。
            //为什么会这样,我还没弄清楚。所以……你最好来解释一下你的代码的思路。
            //那段代码发在下面。
497 490 413 19 343 181 312 252 304 387  825 807 632 617 759 662 804 843 966
删除的值为19//这里挺好理解的,当删除19之后,整个19作为根节点的树,都不见了。
497 490 413 825 807 632 617 759 662 804 843 966
删除的值为497
825 807 632 617 490 413 759 662 804 843 966
删除的值为825
843 807 632 617 490 413 759 662 804 966
删除的值为807
843 966



程序代码:
    else 
    {
        for( tmp = ( *n )->right; tmp->left != NULL; tmp = tmp->left )
        ;

        tmp->left = ( *n )->left;

        tmp =( *n );

        *n = ( *n )->right;

        free_node( &tmp );
    }


[此贴子已经被作者于2017-5-10 18:51编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-10 18:46
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 18楼 九转星河
原来如此,那我不纠结了,我以为是你自己写的,那么你肯定知道自己为什么这样写。

我不学别人的代码,我只学别人的思路。也因为这一点,给我带来很多麻烦,因为思路总是基于正确的代码。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-10 18:58
快速回复:这么多天了,搜索二叉树才搞定了最基础的部分(蹉跎了好些岁月,终于搞 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.021581 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved