二叉查找树(通过外排思想处理大数据)

因为要读的文件很大 ,不能直接一次读进数组,需要通过读一部分,释放内存,再读的方式来解决, 因为直接插入二叉查找(排序)树,则不需要再将排序好的数据先放入别的文件。

#include <stdio.h>
#include <windows.h>
#include <stack>
#include <iostream>
using namespace std;
typedef int ElementType; 
typedef struct TreeNode *Tree;
typedef struct TreeNode *Position;
#define N 250000    //行
#define L 2     //列
const char file_name[50] = "hjy123.txt";
void InOrder( Tree T);
Tree Delete(ElementType X,Tree T);
Tree Insert(ElementType X,Tree T);
Position Find( ElementType X,Tree T);

Position FindMin( Tree T);
struct TreeNode{
    ElementType Data;
    Tree Left,Right;
};
Tree BST = NULL;
void main() {   
    system("color f0");
    int i,j;
    FILE *fp;
    fp=fopen(file_name, "rb");
    long count ;    //记数器,记录已读出的整数
    long **data;
    data=(long **)malloc(N * sizeof(long *));   //分配指向行的指针数组  
    for(i=0;i<N;i++) {
        data[i]=(long *)malloc(L*sizeof(long));  //分配行指针所指向的数组
        //动态二维数组的建立(行列限制内存大小)
    }
    long temp;

    for(int a = 0; a < 200; a++){
        long index[N] = {0};
        count = 0;
        while( 1 == fscanf(fp, "%d", &temp)     ) {
            data [(index[count%L])++] [count%L] = temp;
            count++;
            if(count == 500000) break;
        } 
        for(i = 0,j = 0; i < N ; i++ ) {
            if(data[i][j] == 1) {
                BST = Insert(data[i][j+1],BST);
            } else if(data[i][j] == 2) { 
                if(Find(data[i][j+1],BST) != NULL)      
                    printf("数据%d:查找成功!\n",data[i][j+1]);
                else    
                    printf("数据%d:查找失败!\n",data[i][j+1]);
            } else if(data[i][j] == 3) {
                Delete(data[i][j+1],BST); 
                    printf("数据%d:删除成功!\n",data[i][j+1]);
            } else if(data[i][j] == 0) {
                fclose(fp);
                printf("中序遍历结果如下:\n");
                InOrder(BST);
                printf("\n");
                for(int k=0; k < L; k++){   
                    free(data[k]); //释放所有行空间  
                }  
                free(data); //释放行指针数组 
                exit(0);
            } 
        }
    }
}
Position Find( ElementType X,Tree T) {  //查找
    if(T != NULL){
        if( X < T->Data )       return Find( X, T->Left);
        else if( X > T->Data)   return Find( X, T->Right);
        else                    return T;
    }  
    else    
        return NULL;
}
Tree Insert(ElementType X,Tree T) {     //插入
    if(T == NULL) { //当树为空树  初始化树根
        T = (Tree)malloc(sizeof(struct TreeNode ));
        T->Data = X;
        T->Left = T->Right = NULL;
    }
    else if( X < T->Data)   T->Left = Insert(X, T->Left);
    else if( X > T->Data)   T->Right = Insert(X, T->Right);
    return T;
}
void InOrder(Tree T) {  //非递归中序遍历
    stack<Tree> s;
    Tree P = T;
    while(P != NULL || !s.empty() ) {
        while(P != NULL) {  
            s.push(P);  //压入
            P = P->Left;
        }
        if(!s.empty()) {
            P = s.top();    //取栈顶
            printf("%d ",P->Data);
            s.pop();
            P = P->Right;
        }
    }
}
Position FindMin( Tree T) {     //非递归实现方法
    if( T!=NULL) 
        while(T->Left != NULL)
            T = T->Left;
        return T;
}
Tree Delete(ElementType X, Tree T) {    //删除  分两种情况  
    Position Tmp;
    if(X < T->Data )
        T->Left = Delete( X, T->Left);
    else if(X > T->Data)
        T->Right = Delete( X, T->Right);
    else{   //找到要删除的结点
        if( T->Left && T->Right) {  //被删除结点有左右两个子结点
            Tmp = FindMin( T->Right);   //在右子树中找最小元素填充删除元素
            T->Data = Tmp->Data;
            T->Right = Delete( T->Data, T->Right);
            free( Tmp );            //大数据必须释放内存
        } else {    //被删除结点有一个或无子结点
            Tmp = T;
            if( !T->Left )
                T = T->Right;
            else if( !T->Right)
                T = T->Left;
            free(Tmp);
        }
    }
    return T;   
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值