7.2 线性表的查找(适用于静态查找表)
7.2.1 顺序查找
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef int KeyType;
typedef char InfoType;
//数据元素类型定义
typedef struct
{
KeyType Key;
InfoType otherinfo;
}ElemType;
//顺序表的定义(线性表的顺序存储结构)
typedef struct
{
ElemType* R;
int length;
}SSTable;
void InitSSTable(SSTable& ST);
int Search_Seq(SSTable ST, KeyType key);
int Search_Seq_Key(SSTable ST, KeyType key);
int main()
{
int i = 0;
SSTable ST = {NULL,0};
int m = 0;
int n = 0;
InitSSTable(ST);
for (i = 1; i <= 20; i++)
{
ST.R[i].Key = i;
}
ST.length = 20;
m = Search_Seq(ST, 15);
if (!m)
{
printf("查找不成功。");
}
else
{
printf("15在顺序表ST中的位置数为:%d", m);
}
n = Search_Seq_Key(ST, 15);
if (!n)
{
printf("\n使用设置监视哨法,查找不成功。");
}
else
{
printf("\n使用设置监视哨法,15在顺序表ST中的位置数为:%d", n);
}
return 0;
}
//顺序表的初始化
void InitSSTable(SSTable& ST)
{
ST.R = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
if (!ST.R)
{
printf("初始化顺序表失败。\n");
return;
}
ST.length = 0;
}
//算法7.1 顺序查找
int Search_Seq(SSTable ST, KeyType key)
{
int i = 0;
for (i = ST.length; i >= 1; i--)
{
if (ST.R[i].Key == key)
{
return i;
}
}
return 0;
}
//算法7.2 设置监视哨的顺序查找
int Search_Seq_Key(SSTable ST, KeyType key)
{
int i = 0;
ST.R[0].Key = key;
for (i = ST.length; ST.R[i].Key != key; --i)
{
;
}
return i;
}
7.2.2 折半查找
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef int KeyType;
typedef char InfoType;
//数据元素类型定义
typedef struct
{
KeyType Key;
InfoType otherinfo;
}ElemType;
//顺序表的定义(线性表的顺序存储结构)
typedef struct
{
ElemType* R;
int length;
}SSTable;
void InitSSTable(SSTable& ST);
int Search_Bin(SSTable ST, KeyType key);
int Search_Bin_Re(SSTable ST, KeyType key, int low, int high);
int main()
{
int i = 0;
SSTable ST = {NULL,0};
int m = 0;
int n = 0;
InitSSTable(ST);
for (i = 1; i <= 20; i++)
{
ST.R[i].Key = i;
}
ST.length = 20;
m = Search_Bin(ST, 15);
if (!m)
{
printf("查找不成功。");
}
else
{
printf("15在顺序表ST中的位置数为:%d", m);
}
n = Search_Bin_Re(ST, 15,1,ST.length);
if (!n)
{
printf("\n使用折半查找的递归方式,查找不成功。");
}
else
{
printf("\n使用折半查找的递归方式,15在顺序表ST中的位置数为:%d", n);
}
return 0;
}
//顺序表的初始化
void InitSSTable(SSTable& ST)
{
ST.R = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
if (!ST.R)
{
printf("初始化顺序表失败。\n");
return;
}
ST.length = 0;
}
//算法7.3 折半查找(顺序存储且递增有序排列)
int Search_Bin(SSTable ST, KeyType key)
{
int low = 1;
int high = ST.length;
int mid = 0;
while (low <= high)
{
mid = (low + high) / 2;
if (key == ST.R[mid].Key)
{
return mid;
}
else if (key < ST.R[mid].Key)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return 0;
}
//折半查找的递归程序
int Search_Bin_Re(SSTable ST, KeyType key,int low,int high)
{
if (low > high) // 增加一个退出条件
return 0;
int mid = (low + high) / 2;
if (key == ST.R[mid].Key)
{
return mid;
}
else if(key < ST.R[mid].Key)
{
return Search_Bin_Re(ST, key, low, mid - 1);
}
else
{
return Search_Bin_Re(ST, key, mid + 1, high);
}
return 0;
}
//折半查找的递归程序写法2【采用上面那一种】
int Search_Bin_Re(SSTable ST, KeyType key, int low, int high)
{
int mid = 0;
while (low <= high)
{
mid = (low + high) / 2;
if (key == ST.R[mid].Key)
{
return mid;
}
else if (key < ST.R[mid].Key)
{
return Search_Bin_Re(ST, key, low, mid - 1);
}
else
{
return Search_Bin_Re(ST, key, mid + 1, high);
}
}
return 0;
}
7.2.3 分块查找(对原始表的要求高)
//定义索引表结构体
typedef struct index
{
int key;//最大关键字
int start;//起始地址
}Index[b];
(1)划分数据:首先,将含有n个记录的整个数据表,均匀地划分为b个子表(块),每个块包含s个元素。b为不小于n/s的最小整数;
(2)观察块(不对块中的元素进行排序,只寻找块中的最大值和最小值),对块进行排序:使得块与块之间满足“前一个块的最大值小于后一个块的最小值”的要求。可以将块与块进行交换,如果交换之后,也不能满足,那么说明此数据表不能使用分块查找法。
【应直接选择顺序查找,或对整个数据表进行排序后使用折半查找。】
(3)建立索引表:选择每个块中的最大值作为索引表中该块的最大关键字域,并将该块的第一个位置作为索引表中该块的起始地址域值。【因为第二步,所以此时的索引表一定是有序(递增)的。】
(4)在索引表中使用顺序查找或折半查找确定所在块;因为块中记录是任意排列的,所以在块中使用顺序查找确定目标元素的位置。
7.3 树表的查找(适用于动态查找表)
【均只适用于存储在计算机内存中较小的文件中的查找,统称为内查找法。】
7.3.1 二叉排序树
7.3.1.1 二叉排序树的查找(递归与非递归)
#include <stdio.h>
#include <stdlib.h>
typedef int KeyType;
typedef char InfoType;
//二叉排序树的二叉链表存储表示
typedef struct
{
KeyType Key;
InfoType otherinfo;
}ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode* lchild;
struct BSTNode* rchild;
}BSTNode, * BSTree;
void InitBiTree(BSTree& T);
void CreateBSTree(BSTree& T);
void preOrderTraverse(BSTree T);
void InOrderTraverse(BSTree T);
void posOrderTraverse(BSTree T);
BSTree SearchBST(BSTree T, KeyType key);
BSTree SearchBST_NonRe(BSTree T, KeyType key);
int main()
{
BSTree T = NULL;
int k = 0;
BSTree m = NULL;
BSTree n = NULL;
char choice = '\0';
InitBiTree(T);
printf("请输入二叉排序树的序列:\n");
CreateBSTree(T);
printf("\n二叉排序树链表的先序序列为: ");
preOrderTraverse(T);
printf("\n二叉排序树链表的中序序列为: ");
InOrderTraverse(T);
printf("\n二叉排序树链表的后序序列为: ");
posOrderTraverse(T);
while (1)
{
printf("\n请输入要查找的数:");
scanf_s(" %d", &k);
m = SearchBST(T, k);
if (!m)
{
printf("使用递归方式进行二叉排序树的查找时,查找%d不成功。", k);
}
else
{
printf("使用递归方式进行二叉排序树的查找%d时,以其为根结点的树的中序序列为:", k);
InOrderTraverse(m);
}
n = SearchBST_NonRe(T, k);
if (!n)
{
printf("\n使用非递归方式进行二叉排序树的查找时,查找%d不成功。", k);
}
else
{
printf("\n使用递归方式进行二叉排序树的查找%d时,以其为根结点的树的中序序列为:", k);
InOrderTraverse(n);
}
printf("\n是否继续?(y/n)");
scanf_s(" %c", &choice);
getchar();
if (choice != 'y' && choice != 'Y')
{
break;
}
}
return 0;
}
//初始化二叉排序树
void InitBiTree(BSTree& T)
{
T = NULL;
}
//创建二叉排序树
//输入的二叉排序树的先序序列正确时,输入最后一个结点的关键字域值后,创建程序会自动结束
void CreateBSTree(BSTree& T)
{
KeyType ch = 0;
printf("请输入结点的关键字域值(结点不存在时,输入0):");
scanf_s(" %d", &ch);
if (ch == 0)
{
T = NULL;
}
else if (ch != 0)
{
T = (BSTree)malloc(sizeof(BSTNode));
T->data.Key = ch;
CreateBSTree(T->lchild);
CreateBSTree(T->rchild);
}
}
//先序递归遍历二叉排序树
void preOrderTraverse(BSTree T)
{
if (T) //只有当T不为空时才访问它的成员
{
printf(" %d", T->data.Key);
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
}
//中序递归遍历二叉排序树
void InOrderTraverse(BSTree T)
{
if (T)
{
InOrderTraverse(T->lchild);
printf(" %d", T->data.Key);
InOrderTraverse(T->rchild);
}
}
//后序递归遍历二叉排序树
void posOrderTraverse(BSTree T)
{
if (T)
{
posOrderTraverse(T->lchild);
posOrderTraverse(T->rchild);
printf(" %d", T->data.Key);
}
}
//算法7.4 二叉排序树的递归查找
BSTree SearchBST(BSTree T, KeyType key)
{
if ((!T) || key == T->data.Key)
{
return T;
}
else if (key < T->data.Key)
{
return SearchBST(T->lchild, key);
}
else
{
return SearchBST(T->rchild, key);
}
}
//二叉排序树的非递归查找
BSTree SearchBST_NonRe(BSTree T, KeyType key)
{
BSTree p = T;
while (p != NULL && p->data.Key != key)
{
if (key < p->data.Key)
{
p = p->lchild;
}
else
{
p = p->rchild;
}
}
return p;
}
3, 12, 24 , 37, 45, 53, 61, 78, 90, 100
先根据定义画出任一二叉排序树(满足定义即可),再写出其先序序列,输入程序中即可实现创建该指定二叉树
3, 12, 24 , 37, 45, 53, 61, 78, 90, 100
每个递增序列的二叉排序树不唯一;
每个递增序列的二叉排序树的先序序列不唯一;
每个递增序列的二叉排序树的中序序列是唯一,就是其本身。
7.3.1.2 二叉排序树的创建
#include <stdio.h>
#include <stdlib.h>
#define ENDFLAG -1 //自定义常量,作为输入结束标志
typedef int KeyType;
typedef char InfoType;
//二叉排序树的二叉链表存储表示
typedef struct
{
KeyType Key;
InfoType otherinfo;
}ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode* lchild;
struct BSTNode* rchild;
}BSTNode,*BSTree;
void InitBiTree(BSTree& T);
void InsertBST(BSTree& T, ElemType e);
void CreateBST(BSTree& T);
void preOrderTraverse(BSTree T);
void InOrderTraverse(BSTree T);
void posOrderTraverse(BSTree T);
int main()
{
BSTree T = NULL;
InitBiTree(T);
CreateBST(T);
printf("\n二叉排序树链表的先序序列为: ");
preOrderTraverse(T);
printf("\n二叉排序树链表的中序序列为: ");
InOrderTraverse(T);
printf("\n二叉排序树链表的后序序列为: ");
posOrderTraverse(T);
return 0;
}
//初始化二叉排序树
void InitBiTree(BSTree& T)
{
T = NULL;
}
//算法 7.5 二叉排序树的插入
//前提:当二叉排序树T中不存在关键字等于e.key的数据元素时, 则插入该元素
void InsertBST(BSTree& T, ElemType e)
{
if (!T)
{
BSTree S = (BSTree)malloc(sizeof(BSTNode));
S->data = e;
S->lchild = NULL;
S->rchild = NULL;
T = S; //把新结点*S链接到已找到的插入位置
}
else if (e.Key < T->data.Key)
{
InsertBST(T->lchild, e);
}
else if(e.Key > T->data.Key)
{
InsertBST(T->rchild, e);
}
else
{
printf("当二叉排序树T中存在关键字等于%d的结点,无法插入。\n", e.Key);
return;
}
}
//算法7.6 二叉排序树的创建(在插入操作的基础上,且是从空的二叉排序树开始的)
//依次读人一个关键字为key的结点, 将此结点插人二叉排序树T中
void CreateBST(BSTree& T)
{
InitBiTree(T);
ElemType e = { 0,'\0' };
printf("请输入新结点的关键字key值:");
scanf_s(" %d", &e.Key);
while (e.Key != ENDFLAG) //ENDFLAG为自定义常量-1,作为输入结束标志
{
InsertBST(T, e);
e = { 0,'\0' };
printf("请输入新结点的关键字key值:");
scanf_s(" %d", &e.Key);
}
}
//先序递归遍历二叉排序树
void preOrderTraverse(BSTree T)
{
if (T) //只有当T不为空时才访问它的成员
{
printf(" %d", T->data.Key);
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
}
//中序递归遍历二叉排序树
void InOrderTraverse(BSTree T)
{
if (T)
{
InOrderTraverse(T->lchild);
printf(" %d", T->data.Key);
InOrderTraverse(T->rchild);
}
}
//后序递归遍历二叉排序树
void posOrderTraverse(BSTree T)
{
if (T)
{
posOrderTraverse(T->lchild);
posOrderTraverse(T->rchild);
printf(" %d", T->data.Key);
}
}
7.3.1.2.1 创建任意的二叉排序树
随机输入序列的每个值,根据运行结果的先序、中序、后序序列,确定构造的二叉排序树具体形态。
【该二叉排序树一定也是符合定义的】
一个无序序列可以通过构造一棵二叉排序树而变成一个有序序列, 构造树的过程即为对无序序列进行排序的过程。
无论输入时的序列是何种顺序,CreatBST函数都会返回一个符合二叉排序树定义的正确的二叉排序树。
//算法 7.5 二叉排序树的插入
//前提:当二叉排序树T中不存在关键字等于e.key的数据元素时, 则插入该元素
void InsertBST(BSTree& T, ElemType e)
{
if (!T)
{
BSTree S = (BSTree)malloc(sizeof(BSTNode));
S->data = e;
S->lchild = NULL;
S->rchild = NULL;
T = S; //把新结点*S链接到已找到的插入位置
printf("【a】T->data = %d\n", T->data);
}
else if (e.Key < T->data.Key)
{
printf("【b】T->data = %d\n", T->data);
InsertBST(T->lchild, e);
}
else if (e.Key > T->data.Key)
{
printf("【c】T->data = %d\n", T->data);
InsertBST(T->rchild, e);
}
else
{
printf("当二叉排序树T中存在关键字等于%d的结点,无法插入。\n", e.Key);
return;
}
}
//算法7.6 二叉排序树的创建(在插入操作的基础上,且是从空的二叉排序树开始的)
//依次读人一个关键字为key的结点, 将此结点插人二叉排序树T中
void CreateBST(BSTree& T)
{
InitBiTree(T);
ElemType e = { 0,'\0' };
printf("请输入新结点的关键字key值:");
scanf_s(" %d", &e.Key);
while (e.Key != ENDFLAG) //ENDFLAG为自定义常量-1,作为输入结束标志
{
if (T)
{
printf("【1】T->data = %d\n", T->data);
}
InsertBST(T, e);
if (T)
{
printf("【2】T->data = %d\n", T->data);
}
e = { 0,'\0' };
printf("请输入新结点的关键字key值:");
scanf_s(" %d", &e.Key);
}
}
7.3.1.2.2 创建指定的二叉排序树
3, 12, 24 , 37, 45, 53, 61, 78, 90, 100
先画出想要创建的二叉排序树(必须满足定义),再写出其先序序列,输入程序中即可实现创建该指定二叉树
【此方法比查找中的创建方式输入上更简单】
7.3.1.3 二叉排序树的插入
在已创建的非空排序二叉树中插入新结点
#include <stdio.h>
#include <stdlib.h>
#define ENDFLAG -1 //自定义常量,作为输入结束标志
typedef int KeyType;
typedef char InfoType;
//二叉排序树的二叉链表存储表示
typedef struct
{
KeyType Key;
InfoType otherinfo;
}ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode* lchild;
struct BSTNode* rchild;
}BSTNode, * BSTree;
void InitBiTree(BSTree& T);
int InsertBST(BSTree& T, ElemType e);
void CreateBST(BSTree& T);
void preOrderTraverse(BSTree T);
void InOrderTraverse(BSTree T);
void posOrderTraverse(BSTree T);
int main()
{
BSTree T = NULL;
int key = 0;
ElemType e = { 0,'\0' };
int r = 0;
char choice = '\0';
InitBiTree(T);
CreateBST(T);
printf("\n二叉排序树链表的先序序列为: ");
preOrderTraverse(T);
printf("\n二叉排序树链表的中序序列为: ");
InOrderTraverse(T);
printf("\n二叉排序树链表的后序序列为: ");
posOrderTraverse(T);
//在已创建的非空排序二叉树中插入新结点
while (1)
{
printf("\n请输入要插入的新结点的关键字值:");
scanf_s(" %d", &key);
e.Key = key;
r = InsertBST(T, e);
if (r)
{
printf("\n新二叉排序树链表的先序序列为: ");
preOrderTraverse(T);
printf("\n新二叉排序树链表的中序序列为: ");
InOrderTraverse(T);
printf("\n新二叉排序树链表的后序序列为: ");
posOrderTraverse(T);
}
printf("\n是否继续?(y/n)");
scanf_s(" %c", &choice);
getchar();
if (choice != 'y' && choice != 'Y')
{
break;
}
}
return 0;
}
//初始化二叉排序树
void InitBiTree(BSTree& T)
{
T = NULL;
}
//算法 7.5 二叉排序树的插入
//前提:当二叉排序树T中不存在关键字等于e.key的数据元素时, 则插入该元素
int InsertBST(BSTree& T, ElemType e)
{
if (!T)
{
BSTree S = (BSTree)malloc(sizeof(BSTNode));
S->data = e;
S->lchild = NULL;
S->rchild = NULL;
T = S; //把新结点*S链接到已找到的插入位置
return 1;
}
else if (e.Key < T->data.Key)
{
return InsertBST(T->lchild, e);
}
else if (e.Key > T->data.Key)
{
return InsertBST(T->rchild, e);
}
else
{
printf("当二叉排序树T中存在关键字等于%d的结点,无法插入。\n", e.Key);
return 0;
}
}
//算法7.6 二叉排序树的创建(在插入操作的基础上,且是从空的二叉排序树开始的)
//依次读人一个关键字为key的结点, 将此结点插人二叉排序树T中
void CreateBST(BSTree& T)
{
InitBiTree(T);
ElemType e = { 0,'\0' };
printf("请输入新结点的关键字key值:");
scanf_s(" %d", &e.Key);
while (e.Key != ENDFLAG) //ENDFLAG为自定义常量-1,作为输入结束标志
{
InsertBST(T, e);
e = { 0,'\0' };
printf("请输入新结点的关键字key值:");
scanf_s(" %d", &e.Key);
}
}
//先序递归遍历二叉排序树
void preOrderTraverse(BSTree T)
{
if (T) //只有当T不为空时才访问它的成员
{
printf(" %d", T->data.Key);
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
}
//中序递归遍历二叉排序树
void InOrderTraverse(BSTree T)
{
if (T)
{
InOrderTraverse(T->lchild);
printf(" %d", T->data.Key);
InOrderTraverse(T->rchild);
}
}
//后序递归遍历二叉排序树
void posOrderTraverse(BSTree T)
{
if (T)
{
posOrderTraverse(T->lchild);
posOrderTraverse(T->rchild);
printf(" %d", T->data.Key);
}
}
7.3.1.4 二叉排序树的删除
#include <stdio.h>
#include <stdlib.h>
#define ENDFLAG -1 //自定义常量,作为输入结束标志
typedef int KeyType;
typedef char InfoType;
//二叉排序树的二叉链表存储表示
typedef struct
{
KeyType Key;
InfoType otherinfo;
}ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode* lchild;
struct BSTNode* rchild;
}BSTNode, * BSTree;
void InitBiTree(BSTree& T);
void InsertBST(BSTree& T, ElemType e);
void CreateBST(BSTree& T);
void preOrderTraverse(BSTree T);
void InOrderTraverse(BSTree T);
void posOrderTraverse(BSTree T);
void DeleteBST(BSTree& T, KeyType key);
int main()
{
BSTree T = NULL;
KeyType k = 0;
InitBiTree(T);
CreateBST(T);
printf("\n二叉排序树链表的先序序列为: ");
preOrderTraverse(T);
printf("\n二叉排序树链表的中序序列为: ");
InOrderTraverse(T);
printf("\n二叉排序树链表的后序序列为: ");
posOrderTraverse(T);
printf("\n\n请输入要删除的结点关键字值:");
scanf_s(" %d", &k);
DeleteBST(T, k);
printf("\n\n删除%d后,二叉排序树链表的先序序列为:", k);
preOrderTraverse(T);
printf("\n删除%d后,二叉排序树链表的中序序列为:", k);
InOrderTraverse(T);
printf("\n删除%d后,二叉排序树链表的后序序列为:", k);
posOrderTraverse(T);
return 0;
}
//初始化二叉排序树
void InitBiTree(BSTree& T)
{
T = NULL;
}
//算法 7.5 二叉排序树的插入
//前提:当二叉排序树T中不存在关键字等于e.key的数据元素时, 则插入该元素
void InsertBST(BSTree& T, ElemType e)
{
if (!T)
{
BSTree S = (BSTree)malloc(sizeof(BSTNode));
S->data = e;
S->lchild = NULL;
S->rchild = NULL;
T = S; //把新结点*S链接到已找到的插入位置
}
else if (e.Key < T->data.Key)
{
InsertBST(T->lchild, e);
}
else if (e.Key > T->data.Key)
{
InsertBST(T->rchild, e);
}
else
{
printf("当二叉排序树T中存在关键字等于%d的结点,无法插入。\n", e.Key);
return;
}
}
//算法7.6 二叉排序树的创建(在插入操作的基础上,且是从空的二叉排序树开始的)
//依次读人一个关键字为key的结点, 将此结点插人二叉排序树T中
void CreateBST(BSTree& T)
{
InitBiTree(T);
ElemType e = { 0,'\0' };
printf("请输入新结点的关键字key值:");
scanf_s(" %d", &e.Key);
while (e.Key != ENDFLAG) //ENDFLAG为自定义常量-1,作为输入结束标志
{
InsertBST(T, e);
e = { 0,'\0' };
printf("请输入新结点的关键字key值:");
scanf_s(" %d", &e.Key);
}
}
//先序递归遍历二叉排序树
void preOrderTraverse(BSTree T)
{
if (T) //只有当T不为空时才访问它的成员
{
printf(" %d", T->data.Key);
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
}
//中序递归遍历二叉排序树
void InOrderTraverse(BSTree T)
{
if (T)
{
InOrderTraverse(T->lchild);
printf(" %d", T->data.Key);
InOrderTraverse(T->rchild);
}
}
//后序递归遍历二叉排序树
void posOrderTraverse(BSTree T)
{
if (T)
{
posOrderTraverse(T->lchild);
posOrderTraverse(T->rchild);
printf(" %d", T->data.Key);
}
}
//算法 7.7 二叉排序树的删除
void DeleteBST(BSTree& T, KeyType key)
{
BSTree p = T;
BSTree f = NULL;
BSTree q = NULL;
BSTree s = NULL;
//下面的 while循环从根开始查找关键字等于 key的结点*p
while (p)
{
if (p->data.Key == key)
{
break;
}
f = p;
if (p->data.Key > key)
{
p = p->lchild;
}
else
{
p = p->rchild;
}
}
if (!p)
{
printf("查找关键字值为%d的结点失败。\n", key);
return;
}
//考虑3种情况实现p所指子树内部的处理: *p左右子树均不空、 无右子树、 无左子树
if (p->lchild && p->rchild)
{
q = p;
s = p->lchild;
while (s->rchild)
{
q = s;
s = s->rchild;
}
p->data = s->data;
if (q != p)
{
q->rchild = s->lchild;
}
else
{
q->lchild = s->lchild;
}
free(s);
s = NULL;
return; //退出整个函数,不会受后面释放q的影响
}
else if (!p->rchild)
{
q = p;
p = p->lchild;
}
else if (!p->lchild)
{
q = p;
p = p->rchild;
}
//针对后面两种情况
if (!f)
{
T = p; //如果删除的是根节点,更新根节点(在目标结点左右子树均非空的情况下,不需要更新)
}
else if (q == f->lchild) //将 p 所指的子树挂接到其双亲结点*f相应的位置
{
f->lchild = p;
}
else //if (q == f->rchild)
{
f->rchild = p;
}
free(q); //在目标结点左右子树均非空的情况下不能释放q,此时已经退出整个函数
q = NULL;
}