單鏈表結構及連結串列反轉操作java程式碼實現
阿新 • • 發佈:2020-12-16
資料結構c二叉排序樹基本操作
2020_12_16
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> //二叉排序樹 typedef struct BSTNode { int data; struct BSTNode *lchild; //左孩子 struct BSTNode *rchild; //右孩子 } BSTNode, *BSTree; bool Search(BSTree bst, int key, BSTree f, BSTree *p); void InOderTraverse(BSTree bst) //中序遞迴遍歷二叉樹 { if (bst) { InOderTraverse(bst->lchild); printf("%d ", bst->data); InOderTraverse(bst->rchild); } } static BSTNode *BuyNode(int data) //生成一個節點並進行初始化 { BSTNode *pTmp = (BSTNode *) malloc(sizeof(BSTNode)); if (NULL == pTmp) { exit(0); } pTmp->data = data; pTmp->lchild = NULL; pTmp->rchild = NULL; return pTmp; } bool Insert(BSTree *bst, int key) { if (*bst == NULL) {//空樹 *bst = BuyNode(key); //插入根節點 return true; } BSTNode *p; //先在二叉排序樹中查詢要插入的值是否已經存在 if (!Search(*bst, key, NULL, &p)) //如果查詢失敗,則插入;此時p指向遍歷的最後一個節點 { BSTNode *pNew = BuyNode(key); if (key < p->data) {//將s作為p的左孩子 p->lchild = pNew; } else if (key > p->data) { //將s作為p的右孩子 p->rchild = pNew; } return true; //插入成功 } else { printf("\nThe node(%d) already exists.\n", key); } return false; } /* 刪除分三種情況: (1)被刪除的節點無孩子,說明該節點是葉子節點,直接刪 (2)被刪除的節點只有左孩子或者右孩子,直接刪,並將其左孩子或者右孩子放在被刪節點的位置 (3)被刪除的節點既有右孩子又有右孩子 */ BSTNode *FindParent(BSTree bst, BSTNode *child) { if (NULL == bst) { return NULL; } if (bst->lchild == child || bst->rchild == child) { return bst; } else if (NULL != bst->lchild) { return FindParent(bst->lchild, child); } else if (NULL != bst->rchild) { return FindParent(bst->rchild, child); } return NULL; } void Delete(BSTree *bst, int key) { if (NULL == *bst) { exit(1); //空樹直接報錯 } // BSTNode *f = NULL; BSTNode *p, *q, *s; if (Search(*bst, key, NULL, &p)) //確實存在值為key的節點,則p指向該節點 { if (NULL == p->lchild && p->rchild) //無左孩子,有右孩子 { q = p->rchild; p->data = q->data; //因為兩個節點之間本質的不同在於資料域的不同,而與放在哪個地址沒有關係 p->rchild = q->rchild; p->lchild = q->lchild; free(q); } else if (NULL == p->rchild && p->lchild) //無右孩子,有左孩子 { q = p->lchild; p->data = q->data; p->rchild = q->rchild; p->lchild = q->lchild; free(q); } else if (p->rchild && p->lchild) //既有左孩子,又有右孩子 { 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); } else {//沒有孩子 if (*bst == p) //只有一個根節點 { free(*bst); *bst = NULL; return; } BSTNode *parent = FindParent(*bst, p); if (parent->lchild == p) { parent->lchild = NULL; } else { parent->rchild = NULL; } free(p); } } } //查詢成功時,p指向值為key的節點。如果查詢失敗,則p指向遍歷的最後一個節點,f為根節點。 bool Search(BSTree bst, int key, BSTree f, BSTree *p) { if (!bst) { *p = f; return false; } if (bst->data == key) {//查詢成功,直接返回 *p = bst; return true; } else if (bst->data < key) { return Search(bst->rchild, key, bst, p); } return Search(bst->lchild, key, bst, p); } int main() { freopen("input.txt", "r", stdin); printf("請輸入數字個數:\n"); int n, i; scanf("%d", &n); BSTNode *root = NULL, *p; printf("請輸入要插入的數字:\n"); for (i = 0; i < n; i++) { int x; scanf("%d", &x); Insert(&root, x); } InOderTraverse(root); printf("請輸入要查詢的數字:\n"); int x; scanf("%d", &x); if (Search(root, x, NULL, &p)) printf("存在此數。\n"); else printf("不存在此數。\n"); // printf("%d ", Insert(&root, 45)); //輸出0表示插入失敗,輸出1表示插入成功 // printf("%d\n", Insert(&root, 4)); printf("請輸入刪除數字個數:\n"); scanf("%d", &n); printf("請輸入要刪除的數字:\n"); for (i = 0; i < n; i++) { int x; scanf("%d", &x); Delete(&root, x); } printf("刪除後順序為:\n"); InOderTraverse(root); return 0; }