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