数据结构与算法题目集(中文)函数题

PTA数据结构与算法题目集(中文)的函数题部分。本身底子就差,还有好多语法知识都快忘了,这里写出来相当于一个查漏补缺了。不能一蹴而就。

文章目录

    • 6-1 单链表逆转
    • 6-2 顺序表操作集
    • 6-3 求链式表的表长
    • 6-4 链式表的按序号查找
    • 6-5 链式表操作集
    • 6-6 带头结点的链式表操作集
    • 6-7 在一个数组中实现两个堆栈
    • 6-8 求二叉树高度
    • 6-9 二叉树的遍历
    • 6-10 二分查找
    • 6-11 先序输出叶结点
    • 6-12 二叉搜索树的操作集
  • 总结


6-1 单链表逆转

图解
数据结构与算法题目集(中文)函数题_第1张图片
用头插法去做,1->3中,1被取出作为头,接着3被取出放在1的前面作为新头。但是要注意顺序,这个容易出错!!!
另外就是结构体链表的创建和输出。

#include 
#include 

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表 */

List Reverse( List L );

int main()
{
    List L1, L2;
    L1 = Read();
    L2 = Reverse(L1);
    Print(L1);
    Print(L2);
    return 0;
}

/* 你的代码将被嵌在这里 */


List Reverse( List L )
{
    List N = NULL; //结构体指针,新表头
    List p = NULL; //头插法指针
    while(L)
    {
       p = L;
       L = L->Next; //为啥要放在这里?!
       p->Next = N; //!!!这里改变了
       printf("%d\n", p->Data);
       N = p;
       //L = L->Next; //放在这个地方是错的
    }
    return N;
}

List Read()
{
     List L = (List)malloc(sizeof(struct Node));//创建头结点
     List beg = L;
     int n = 0;
     scanf("%d", &n);
     scanf("%d", &L->Data);
     List p = NULL; //临时指针
     for(int i=0;i<n-1;i++){   //循环建立数据结点
        p = (List)malloc(sizeof(struct Node));
         //将结点s插在原开始节点之前,头结点之后
        scanf("%d", &p->Data);
        //L一直指向最后一个节点,而的指针beg才是指向链表头结点的
        L->Next = p;
        L = L->Next;
    }
    L->Next = NULL;
    return beg;
}

void Print( List L )
{
    while(L)
    {
        printf("%d",L->Data);
        L = L->Next;
    }
    printf("\n");
}

6-2 顺序表操作集

顺序表有些小小的特征,都在注释里

#include 
#include 

#define MAXSIZE 5
#define ERROR -1
typedef enum {false, true} bool;
typedef int ElementType;
typedef int Position; //从0开始的
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE]; //线性表是紧挨着的,中间没有空格
    Position Last; /* 保存线性表中最后一个元素的位置 */
};

List MakeEmpty();
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

int main()
{
    List L;
    ElementType X;
    Position P;
    int N;

    L = MakeEmpty();
    //printf("L:::%d\n", L->Last);
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        if ( Insert(L, X, 0)==false )
            printf(" Insertion Error: %d is not in.\n", X);
    }

    //printf("LNEXT:::%d\n", L->Last); //为啥这里的last变了,啊啊啊,因为初始化的时候应该是-1

    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else
            printf("%d is at position %d.\n", X, P);
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &P);
        if ( Delete(L, P)==false )
            printf(" Deletion Error.\n");
        if ( Insert(L, 0, P)==false )
            printf(" Insertion Error: 0 is not in.\n");
    }
    return 0;
}

/* 你的代码将被嵌在这里 */

List MakeEmpty()
{
    List L = (List)malloc(sizeof(struct LNode));
    L->Last = -1;
    return L;
}

Position Find( List L, ElementType X )
{
    Position n = 0;
    //printf("L:::%d", L->Last);
    while(n <= L->Last)
    {
        if(L->Data[n] == X)
        {
            return n;
        }
        //printf(":::%d", n);
        n++;
    }
    //printf("L:::%d", L->Last);
    return ERROR;
}

/*
顺序表中插入数据元素,无非三种情况:
在表头插入;
在表的中间某个位置插入;
直接尾随顺序表,作为表的最后一个元素;

无论在顺序表的什么位置插入数据元素,解决办法都是:找到要插入的位置,
将后续数据元素整体向后移动一个位置,最后直接在腾出来的位置上插入指定的数据元素。
*/
bool Insert( List L, ElementType X, Position P )
{ //插入的话要把后面的往后挪
    if(L->Last+1 >= MAXSIZE)
    {
        printf("FULL");
        return false;
    }
    else if(P > L->Last+1)
    {
        printf("ILLEGAL POSITION");
        return false;
    }
    else
    {
        int tmp;//暂存往后挪的那个数字
        L->Last += 1;
        while(P < L->Last)
        {
            tmp = L->Data[P];
            L->Data[P] = X;
            X = tmp;
            P++;
        }
        L->Data[P] = X;
        //printf("L:::%d\n", L->Last);
        return true;
    }
}

bool Delete( List L, Position P )
{
    if(P > L->Last || P < 0)
    {
        printf("POSITION %d EMPTY", P);
        return false;
    }
    L->Last = L->Last-1;
    while(P <= L->Last)
    {
       L->Data[P] = L->Data[P+1];
    }
    return true;
}

6-3 求链式表的表长

读到-1时停止输入

#include 
#include 

typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode List;

List Read(); /* 细节在此不表 */

int Length( List L );

int main()
{
    List L = Read();
    printf("%d\n", Length(L));
    return 0;
}

List Read()
{
     List L = (List)malloc(sizeof(struct LNode));
     List beg = L;
     int n = 0;
     List p = NULL; //临时指针
     scanf("%d", &n);
     if(n != -1)
        L->Data = n;
     scanf("%d", &n);
     while(n != -1 )
     {
        p = (List)malloc(sizeof(struct LNode));
        p->Data = n;
        L->Next = p;
        L = L->Next;
        scanf("%d", &n);
     }
    L->Next = NULL;
    //printf("finish\n");
    return beg;
}

/* 你的代码将被嵌在这里 */
int Length( List L )
{
    int sum = 0;
    while(L)
    {
       sum++;
       L = L->Next;
    }
    return sum;
}

6-4 链式表的按序号查找

#include 
#include 

#define ERROR -1
typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode
{
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode List;

List Read(); /* 细节在此不表 */

ElementType FindKth( List L, int K );

int main()
{
    int N, K;
    ElementType X;
    List L = Read();
    scanf("%d", &N);
    while ( N-- )
    {
        scanf("%d", &K);
        X = FindKth(L, K);
        if ( X!= ERROR )
            printf("%d ", X);
        else
            printf("NA ");
    }
    return 0;
}

List Read()
{
    List L = (List)malloc(sizeof(struct LNode));
    List beg = L;
    int n = 0;
    List p = NULL; //临时指针
    scanf("%d", &n);
    if(n != -1)
        L->Data = n;
    scanf("%d", &n);
    while(n != -1 )
    {
        p = (List)malloc(sizeof(struct LNode));
        p->Data = n;
        L->Next = p;
        L = L->Next;
        scanf("%d", &n);
    }
    L->Next = NULL;
    //printf("finish\n");
    return beg;
}
/* 你的代码将被嵌在这里 */
ElementType FindKth( List L, int K )
{
    int num = 1;
    while(L)
    {
        if(num == K)
        {
            return L->Data;
        }
        L = L->Next; //注意是指向新节点后就要判断是否为空
        num++;
    }
    return ERROR;
}

6-5 链式表操作集

#include 
#include 

#define ERROR NULL
typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode
{
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

Position Find( List L, ElementType X );
List Insert( List L, ElementType X, Position P );
List Delete( List L, Position P );
void Print( List L );

int main()
{
    List L;
    ElementType X;
    Position P, tmp;
    int N;

    L = NULL;
    scanf("%d", &N);
    while ( N-- )
    {
        scanf("%d", &X);
        L = Insert(L, X, L);
        if ( L==ERROR )
            printf("Wrong Answer\n");
    }

    //Print( L );
    //printf("--------------");

    scanf("%d", &N);
    while ( N-- )
    {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else
        {
            L = Delete(L, P);
            printf("%d is found and deleted.\n", X);
            if ( L==ERROR )
                printf("Wrong Answer or Empty List.\n");
        }
    }
    L = Insert(L, X, NULL);
    if ( L==ERROR )
        printf("Wrong Answer\n");
    else
        printf("%d is inserted as the last element.\n", X);
    P = (Position)malloc(sizeof(struct LNode));
    tmp = Insert(L, X, P);
    if ( tmp!=ERROR )
        printf("Wrong Answer\n");
    tmp = Delete(L, P);
    if ( tmp!=ERROR )
        printf("Wrong Answer\n");
    for ( P=L; P; P = P->Next )
        printf("%d ", P->Data);
    return 0;
}

void Print( List L )
{
    while(L)
    {
        printf("%d",L->Data);
        L = L->Next;
    }
    printf("\n");
}

/* 你的代码将被嵌在这里 */
Position Find( List L, ElementType X )
{
    List pos = L;
    while(pos)
    {
        if(pos->Data == X)
        {
            return pos;
        }
        pos = pos->Next;
    }
    return ERROR;
}

List Insert( List L, ElementType X, Position P )
{
    List pos = L;
    List node = (List)malloc(sizeof(struct LNode));
    node->Data = X;
    if(L == P)
    {
        node->Next = pos;
        return node;
    }
    while(pos)
    {
        if(pos->Next == P)
        {
            node->Next = pos->Next;
            pos->Next = node;
            return L;
        }
        pos = pos->Next;
    }
    printf("Wrong Position for Insertion\n");
    return ERROR;
}

List Delete( List L, Position P )
{
    List pos = L;
    if(L == P)
    {
        return L->Next;
    }
    while(pos)
    {
        if(pos->Next == P)
        {
            //删除时要找到前一个
            pos->Next = P->Next;
            return L;
        }
        pos = pos->Next;
    }
    printf("Wrong Position for Deletion\n");
    return ERROR;
}

6-6 带头结点的链式表操作集

#include 
#include 

#define ERROR NULL
typedef enum {false, true} bool;
typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

List MakeEmpty();
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

int main()
{
    List L;
    ElementType X;
    Position P;
    int N;
    bool flag;

    L = MakeEmpty();
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        flag = Insert(L, X, L->Next);
        if ( flag==false ) printf("Wrong Answer\n");
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else {
            flag = Delete(L, P);
            printf("%d is found and deleted.\n", X);
            if ( flag==false )
                printf("Wrong Answer.\n");
        }
    }
    flag = Insert(L, X, NULL);
    if ( flag==false ) printf("Wrong Answer\n");
    else
        printf("%d is inserted as the last element.\n", X);
    P = (Position)malloc(sizeof(struct LNode));
    flag = Insert(L, X, P);
    if ( flag==true ) printf("Wrong Answer\n");
    flag = Delete(L, P);
    if ( flag==true ) printf("Wrong Answer\n");
    for ( P=L->Next; P; P = P->Next ) printf("%d ", P->Data);
    return 0;
}
/* 你的代码将被嵌在这里 */
List MakeEmpty()
{
    List node = (List)malloc(sizeof(struct LNode));
    node->Next = NULL;
    return node;
}
Position Find( List L, ElementType X )
{
    List pos = L->Next;
    while(pos)
    {
        if(pos->Data == X)
        {
            return pos;
        }
        pos = pos->Next;
    }
    return ERROR;
}
bool Insert( List L, ElementType X, Position P )
{
    List pos = L->Next;
    List node = (List)malloc(sizeof(struct LNode));
    node->Data = X;
    if(pos == P)
    {
        node->Next = pos;
        L->Next = node;
        return true;
    }
    while(pos)
    {
        if(pos->Next == P)
        {
            node->Next = pos->Next;
            pos->Next = node;
            return true;
        }
        pos = pos->Next;
    }
    printf("Wrong Position for Insertion\n");
    return false;
}
bool Delete( List L, Position P )
{
    List pos = L->Next;
    if(pos == P)
    {
        L->Next = pos->Next;
        return true;
    }
    while(pos)
    {
        if(pos->Next == P)
        {
            //删除时要找到前一个
            pos->Next = P->Next;
            return true;
        }
        pos = pos->Next;
    }
    printf("Wrong Position for Deletion\n");
    return false;
}

6-7 在一个数组中实现两个堆栈

必须检查Stack是否为NULL,要不然一个测试案例都过不了

Stack CreateStack( int MaxSize )
{
    Stack s = (Stack)malloc(sizeof(struct SNode));
    s->MaxSize = MaxSize;
    //动态开辟一个数组
    s->Data = (ElementType*)malloc(MaxSize*sizeof(ElementType));
    //栈底就是数组的两个边界
    s->Top1 = -1;
    s->Top2 = MaxSize;
    return s;
}

bool Push( Stack S, ElementType X, int Tag )
{
    if (!S) return false;
    if(S->Top1+1 == S->Top2)
    {
        printf("Stack Full\n");
        return false;
    }
    if(Tag == 1)
    {
        S->Data[++S->Top1] = X;
    }
    else
    {
        S->Data[--S->Top2] = X;
    }
     return true;
}

ElementType Pop( Stack S, int Tag )
{
    if (!S) return ERROR;
    if(Tag == 1)
    {
        if(S->Top1 == -1)
        {
            printf("Stack 1 Empty\n");
            return ERROR;
        }
        return S->Data[S->Top1--];
    }
    else
    {
        if(S->Top2 == S->MaxSize)
        {
            printf("Stack 2 Empty\n");
            return ERROR;
        }
        return S->Data[S->Top2++];
    }
}

6-8 求二叉树高度

我们一定要考虑几个条件:

  1. 二叉树空 return 0
  2. 只有一个节点的情况
  3. 一般情况
        if (ch=='#')
        {//没孩子
            BT=NULL;
        }
        else
        {
            BT=(BinTree)malloc(sizeof(BinTree));
            BT->Data=ch;
            CreatBinTree(BT->Left);
            CreatBinTree(BT->Right);
        }

当用先序创造一棵树时,可以画出递归函数的前进:
数据结构与算法题目集(中文)函数题_第2张图片
计算树的高度,每次左右节点递归完,到中间节点处要做个比较。

int GetHeight( BinTree BT )
{
    if (!BT) return 0;
    else
    {
        int left = GetHeight( BT->Left )+1;
        int right = GetHeight( BT->Right )+1;
        return (left>right) ? left : right;
    }
}

6-9 二叉树的遍历

//前中后序遍历都是有规律的
void InorderTraversal( BinTree BT )
{//中序
    if(!BT)
    {
        return;
    }
    InorderTraversal( BT->Left );
    printf(" %c",BT->Data);
    InorderTraversal( BT->Right );
}

void PreorderTraversal( BinTree BT )
{//前序
    if(!BT)
    {
        return;
    }
    printf(" %c",BT->Data);
    PreorderTraversal( BT->Left );
    PreorderTraversal( BT->Right );
}

void PostorderTraversal( BinTree BT )
{//后序
    if(!BT)
    {
        return;
    }
    PostorderTraversal( BT->Left );
    PostorderTraversal( BT->Right );
    printf(" %c",BT->Data);
}

void LevelorderTraversal( BinTree BT )
{
    // 所以说队列还是很好写的
    if(BT == NULL)
    {
        return;
    }
    BinTree queen[100];
    int front=0,rear=0;
    //queen[0] = BT; //不能这么写,要不然进不了循环
    queen[rear++] = BT;
    while(front != rear)
    {
        BT = queen[front++];//段错误?因为没写而这句话
        if(BT->Left)
            queen[rear++] = BT->Left;
        if(BT->Right)
            queen[rear++] = BT->Right;
        printf(" %c", BT->Data);
    }
}

但是构造一棵树的时候用到了引用
数据结构与算法题目集(中文)函数题_第3张图片

所以要换到cpp里运行检查错误

void CreatBinTree(BinTree &BT)
{//CreatBinTree(BT);这样写BT是个空的
    char ch;
    scanf("%c", &ch);

    if (ch=='#')
    {
        //没孩子
        BT=NULL;
    }
    else
    {
        BT = (BinTree)malloc(sizeof(BinTree));
        BT->Data = ch;
        CreatBinTree(BT->Left);
        CreatBinTree(BT->Right);
    }
}

6-10 二分查找

Position BinarySearch( List L, ElementType X )
{
    //元素从下标1开始存储
    if(!L){return NotFound;}
    Position min = 1;
    Position max = L->Last;
    Position now;
    while(min <= max)
    {
        now = (min+max)/2;
        if(L->Data[now] > X)
        {
            max = now-1;
        }
        else if(L->Data[now] < X)
        {
            min = now+1;
        }
        else
        {
            return now;
        }
    }
    return NotFound;
}

6-11 先序输出叶结点

void PreorderPrintLeaves( BinTree BT )
{
    if(!BT){return;}
    if(!BT->Left && !BT->Right)
    {
        printf(" %c", BT->Data);
        return;
    }
    PreorderPrintLeaves(BT->Left);
    PreorderPrintLeaves(BT->Right);
}

6-12 二叉搜索树的操作集

二叉搜索树又叫「平衡二叉树」。
它的特点:左子树<根<右子树。
数据结构与算法题目集(中文)函数题_第4张图片
先放除了删除部分的代码:

#include 
#include 

typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode
{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

void PreorderTraversal( BinTree BT ); /* 先序遍历,由裁判实现,细节不表 */
void InorderTraversal( BinTree BT );  /* 中序遍历,由裁判实现,细节不表 */

BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );

int main()
{
    BinTree BST, MinP, MaxP, Tmp;
    ElementType X;
    int N, i;

    BST = NULL;
    scanf("%d", &N);
    for ( i=0; i<N; i++ )
    {
        scanf("%d", &X);
        BST = Insert(BST, X);
    }
    printf("Preorder:");
    PreorderTraversal(BST);
    printf("\n");
    MinP = FindMin(BST);
    MaxP = FindMax(BST);
    scanf("%d", &N);
    for( i=0; i<N; i++ )
    {
        scanf("%d", &X);
        Tmp = Find(BST, X);
        if (Tmp == NULL)
            printf("%d is not found\n", X);
        else
        {
            printf("%d is found\n", Tmp->Data);
            if (Tmp==MinP)
                printf("%d is the smallest key\n", Tmp->Data);
            if (Tmp==MaxP)
                printf("%d is the largest key\n", Tmp->Data);
        }
    }
    scanf("%d", &N);
    for( i=0; i<N; i++ )
    {
        scanf("%d", &X);
        BST = Delete(BST, X);
    }
    printf("Inorder:");
    InorderTraversal(BST);
    printf("\n");
    return 0;
}

void InorderTraversal( BinTree BT )
{
    //中序
    if(!BT)
    {
        return;
    }
    InorderTraversal( BT->Left );
    printf(" %d",BT->Data);
    InorderTraversal( BT->Right );
}

void PreorderTraversal( BinTree BT )
{
    //前序
    if(!BT)
    {
        return;
    }
    printf(" %d",BT->Data);
    PreorderTraversal( BT->Left );
    PreorderTraversal( BT->Right );
}

/* 你的代码将被嵌在这里 */

BinTree Insert( BinTree BST, ElementType X )
{
    BinTree node = (BinTree)malloc(sizeof(struct TNode));
    node->Data = X;
    node->Left = NULL;
    node->Right = NULL;
    if(!BST)
    {
        return node;
    }
    BinTree p = BST;
    while(1)
    {
        if(p->Data > X)
        {
            if(!p->Left)
            {
                p->Left = node;
                return BST;
            }
            p = p->Left;
        }
        else if(p->Data < X)
        {
            if(!p->Right)
            {
                p->Right = node;
                return BST;
            }
            p = p->Right;
        }
    }
}

Position Find( BinTree BST, ElementType X )
{
    BinTree p = BST;
    while(p)
    {
        if(p->Data > X)
        {
            p = p->Left;
        }
        else if(p->Data < X)
        {
            p = p->Right;
        }
        else
        {
            return p;
        }
    }
    return NULL;
}

Position FindMin( BinTree BST )
{
    if (!BST)
    {
        return NULL;
    }
    while (BST->Left)
    {
        BST=BST->Left;
    }
    return BST;
}

Position FindMax( BinTree BST )
{
    if (!BST)
    {
        return NULL;
    }

    while (BST->Right)
    {
        BST=BST->Right;
    }

    return BST;
}

解决了为啥不能随便删的疑惑以及有两个子节点,用左儿子或者右儿子的值替换改节点的值,然后删除那个叶子节点。注意用节点的值替换不必用节点替换。

进一步简化:有两个子节点,将右子树最小值替换当前root值,或者左子树最大值去替换,然后删掉那个最小值叶节点。

BinTree Delete( BinTree BST, ElementType X )
{
    //查找,正是因为递归才能保留双亲节点
    //如果用Find查找返回一个新指针,是没法改变值的
    if (!BST)
    {
        //当递归找到空节点或者本身为空时就退出
        printf("Not Found\n");
        return NULL;
    }
    else if (X > BST->Data)
    {
        BST->Right = Delete(BST->Right, X);
    }
    else if (X < BST->Data)
    {
        BST->Left = Delete(BST->Left, X);
    }

    //找到了
    else if(X == BST->Data)
    {
        Position tmp;
        if (BST->Left && BST->Right)
        {//左右双亲都有
            tmp = FindMin(BST->Right);
            BST->Data = tmp->Data;
            //替换掉值之后的任务就是,把用来替换那个删掉(但是递归你不用考虑是怎么被删掉的)
            BST->Right = Delete(BST->Right, BST->Data);
        }
        else
        {
            if (BST->Left == NULL)
                BST = BST->Right;
            else if (BST->Right == NULL)
                BST = BST->Left;
            else
                free(BST);
        }
    }
    return BST;
}

如果不用递归去做,那么删除的时候不能用Find函数之类的了,因为你的拿到双亲节点,也就不能只是替换节点的值那么简单了。

BinTree Delete( BinTree BST, ElementType X )
{
    if(!BST)
    {
        //空的直接不找了
        printf("Not Found\n");
        return BST;
    }
    //由于删除的时候要保留前一个节点,寻找就不能调用那个寻找函数了
    BinTree p = BST;
    BinTree parent = NULL;
    while(1)
    {
        //找节点,按照道理找不到就退出循环
        if (X > p->Data)
        {
            if(p->Right != NULL)
            {
                parent = p;
                p = p->Right;
            }
            else
                break;
        }
        else if (X < p->Data)
        {
            if(p->Left != NULL)
            {
                parent = p;
                p = p->Left;
            }
            else
                break;
        }
        
        //找到了节点,分情况删除
        else if (X == p->Data)
        {
            //当为叶结点时
            if(p->Left == NULL && p->Right == NULL)
            {
                    if(parent->Left == p)
                    {
                        parent->Left = NULL;
                    }
                    else if(parent->Right == p)
                    {
                        parent->Right = NULL;
                    }
                    else //没有双亲,是个单独的节点
                    	return NULL;
            }
            //当为一个子结点时
            else if(p->Left == NULL)
            {
                if(parent == NULL)
                {
                    return p->Right;
                }
                else if(parent->Left == p)
                {
                    parent->Left = p->Right;
                }
                else
                {
                    parent->Right = p->Right;
                }
            }
            else if(p->Right == NULL)
            {
                if(parent == NULL)
                {
                    return p->Left;
                }
                else if(parent->Left == p)
                {
                    parent->Left = p->Left;
                }
                else
                {
                    parent->Right = p->Left;
                }
            }
            else
            {
                //非递归的方法就得额外保存双亲,不是仅仅替换值就可以了。
                BinTree tmp = FindMin(p->Right);
                p->Data = tmp->Data;
                //tmp = NULL; //这样是错的
                //去置空孩子节点
                p = p->Right;
                while (p->Left != tmp)
                {
                    p = p->Left;
                }
                //此时被删除的点p->Left一定是没有左孩子的,但可能有右孩子
                if(p->Left->Right != NULL)
                {
                    p->Left = p->Left->Right;
                }
                else
                    p->Left = NULL;
            }
            return BST;
        }
    }
    printf("Not Found\n");
    return BST;
}

这道题的一些测试数据:

1
7
2
5 9
3
5 9 7

5
5 4 3 2 1
2
6 -1
5
-1 6 5 1 3

总结

比起以前来说好多了,但还是菜,多练练吧。

你可能感兴趣的:(算法,数据结构,算法,链表)