数据结构与实现——数组、矩阵、链表、队列、栈、对象、二叉树和红黑树

1、动态数组

动态数组是相对于静态数组而言的,可以灵活的在运行时确定数组的大小,而静态数组操作简单但必须在编译时刻确定数组的大小;实现了一维、二维、三维数组的动态创建,数组的动态扩展和动态缩小。并对C语言中的三个内存申请函数extern void *malloc(unsigned int num_bytes);void *calloc(sint_t n, size_t size);extern void *realloc(void *mem_address, unsigned int num_bytes)的使用有了直观的认识。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void onedimension();
void twodimension();
void threedimension();
void dynamicexpand();
void dynamicreduce();

main()
{
    srand(time(NULL));
    printf("\t\tOne dimension dynamic array:\n");
    onedimension();
    printf("\n\t\tTwo dimension dynamic array:\n");
    twodimension();
    printf("\n\t\tThree dimension dynamic array:\n");
    threedimension();
    printf("\t\tDynamic array expand:\n");
    dynamicexpand();
    printf("\n\t\tDynamic array reduce:\n");
    dynamicreduce();
    return 0;
}

void onedimension()
{
    int i, n1;
    int *arr1;

    printf("Enter the length of one-dimension dynamic array: ");
    scanf("%d", &n1);
    arr1 = (int *)calloc(n1, sizeof(int));
    printf("The value of initial dynamic array:\n");
    for (i = 0; i < n1; i++)
        printf("%7d ", arr1[i]);
    printf("\nThe value of reassignmenting of dynamic array:\n");
    for (i = 0; i < n1; i++) {
        arr1[i] = rand() % 1000;
        printf("%7d ", arr1[i]);
    }
    printf("\n");
    free(arr1);
    return;
}

void twodimension()
{
    int i, j, n1, n2;
    int **arr2;

    printf("Enter the length of the first dimension: ");
    scanf("%d", &n1);
    arr2 = (int **)malloc(n1 * sizeof(int *));
    printf("Enter the length of the second dimension: ");
    scanf("%d", &n2);
    for (i = 0; i < n1; i++)
        arr2[i] = (int *)malloc(n2 * sizeof(int));
    printf("The value of initial dynamic array:\n");
    for (i = 0; i < n1; i++) {
        for (j = 0; j < n2; j++) {
            printf("%7d ", arr2[i][j]);
        }
        printf("\n");
    }
    printf("The value of reassignmenting of dynamic array:\n");
    for (i = 0; i < n1; i++) {
        for (j = 0; j < n2; j++) {
            arr2[i][j] = rand() % 1000;
            printf("%7d ", arr2[i][j]);
        }
        printf("\n");
    }
    //printf("\n");
    for (i = 0; i < n1; i++)
        free(arr2[i]);
    free(arr2);
    return;
}

void threedimension()
{
    int i, j, k, n1, n2, n3;
    int ***arr3;

    printf("Enter the length of the first dimension: ");
    scanf("%d", &n1);
    printf("Enter the length of the second dimension: ");
    scanf("%d", &n2);
    printf("Enter the length of the third dimension: ");
    scanf("%d", &n3);
    arr3 = (int ***)malloc(n1 * sizeof(int **));
    for (i = 0; i < n1; i++) {
        arr3[i] = (int **)malloc(n2 * sizeof(int *));
        for (j = 0; j < n2; j++) {
            arr3[i][j] = (int *)malloc(n3 * sizeof(int));
            for (k = 0; k < n3; k++) {
                arr3[i][j][k] = rand() % 1000;
                printf("%7d ", arr3[i][j][k]);
            }
            printf("\n");
        }
        printf("\n");
    }
    for(i = 0; i < n1; i++) {
        for (j = 0; j < n2; j++) {
            free(arr3[i][j]);
        }
        free(arr3[i]);
    }
    free(arr3);
    return;
}

void dynamicexpand()
{
    int i, n1, n2;
    int *arro, *arre;

    printf("Enter the length of array to be created: ");
    scanf("%d", &n1);
    arro = (int *)calloc(n1, sizeof(int));
    printf("Enter the length of array to be expanded: ");
    scanf("%d", &n2);
    for (i = 0; i < n2; i++) {
        arro[i] = rand() % 1000;
        printf("%7d", arro[i]);
        arre = (int *)realloc(arro, (i + 2) * sizeof(int));
        if (arre)
            arro = arre;
        else {
            fputs("Error: not enough memory!", stderr);
            exit(1);
        }
    }
    printf("\n");
    free(arro);
    return;
}

void dynamicreduce()
{
    int i, n1, n2;
    int *n, *p;

    printf("Enter the length of array to be created: ");
    scanf("%d", &n1);
    n = (int *)calloc(n1, sizeof(int));
    if (!n) {
        fputs("Error: not enough memory!", stderr);
        exit(1);
    }
    printf("Enter the length of array to be reduced: ");
    scanf("%d", &n2);
    for (i = 0; i < n1; i++) {
        n[i] = rand() % 1000;
        printf("%7d", n[i]);
    }
    printf("\n");
    p = (int *)realloc(n, n2 * sizeof(int));
    for (i = 0; i < n2; i++)
        printf("%7d", p[i]);
    printf("\n");
    free(p);
    return;

}


2.稀疏矩阵

定义稀疏矩阵并实现压缩存储,采用了三元组线性存储方法。

#include <stdio.h>
#include <stdio.h>
#include <time.h>

#define MAXROW 10
#define MAXCOL 10
#define MAXSIZE 100

typedef struct triple
{
    int row, col;
    int ele;
} TRIPLE;

typedef struct tsmatrix
{
    TRIPLE data[MAXSIZE + 1];
    int mu, nu, tu;
} TSMATRIX;

int matrix[MAXROW + 1][MAXCOL + 1];

void createsparsematrix();
void compressionstorage();

main()
{
    printf("\t\tSparse matrix to be compressed\n");
    createsparsematrix();
    printf("\n\t\tCompression matrix to be storaged\n");
    compressionstorage();

    return 0;
}

void createsparsematrix()
{
    int i, j, r;

    srand(time(NULL));
    for (i = 1; i <= MAXROW; i++) {
        for (j = 1; j <= MAXCOL; j++) {
            if ((r = rand() % 10 + 1) == i || r == j)
                matrix[i][j] = r;
            else
                matrix[i][j] = 0;
            printf("%3d", matrix[i][j]);
        }
        printf("\n");
    }
    return;
}

void compressionstorage()
{
    int i, j;
    TSMATRIX* tsmatrix;
    TRIPLE *triple;

    triple = (TRIPLE *)malloc(sizeof(TRIPLE));
    tsmatrix = (TSMATRIX *)malloc(sizeof(TSMATRIX));
    tsmatrix->mu = MAXROW;
    tsmatrix->nu = MAXCOL;
    tsmatrix->tu = 0;
    for (i = 0; i <= tsmatrix->mu; i++) {
        for (j = 0; j <= tsmatrix->nu; j++) {
            if (matrix[i][j] != 0) {
                triple->row = i;
                triple->col = j;
                triple->ele = matrix[i][j];
                tsmatrix->tu++;
                tsmatrix->data[tsmatrix->tu] = *triple;
            }
        }
    }
    printf("Row\tColumn\tValue\n");
    for (i = 1; i <= tsmatrix->tu; i++) {
        printf("%2d\t", tsmatrix->data[i].row);
        printf("%2d\t", tsmatrix->data[i].col);
        printf("%2d\n", tsmatrix->data[i].ele);
    }
    free(triple);
    free(tsmatrix);
    return;
}


3、栈(Stacks)

后进先出LIFO,源代码使用数组实现栈,对数据结构栈的三个的操作时间复杂度都是O(1);

#include<stdio.h>
#include<stdlib.h>

#define STACKSIZE 1000

typedef struct
{
    size_t size;
    int items[STACKSIZE];
} STACK;

int isEmpty(STACK *);
void push(STACK *, int);
int pop(STACK *);

main()
{
    STACK *s;
    int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int i;

    s = (STACK *)malloc(sizeof(STACK));
    s->size = 0;
    if (isEmpty(s))
        printf("Stack is empty\n");
    else
        printf("Stack is not empty\n");
    for (i = 0; i < sizeof(array)/sizeof(array[0]); i++)
        push(s, array[i]);
    printf("The size of stack is %d\n", s->size);
    printf("The elements of stack:  ");
    while(!isEmpty(s))
        printf("%d ", pop(s));
    printf("\nThe size of stack is %d\n", s->size);
    return 0;
}

int isEmpty(STACK *s)
{
    if (s->size == 0)
        return 1;
    else
        return 0;
}

void push(STACK *s, int x)
{
    if (s->size == STACKSIZE) {
        fputs("Error: stack overflow\n", stderr);
        abort();
    }
    else
        s->items[s->size++] = x;
}

int pop(STACK *s)
{
    if (s->size == 0) {
        fputs("Error: stack underflow\n", stderr);
        abort();
    }
    else
        return s->items[--s->size];
}


4.队列(Queues)

与栈操作的相反,属于先进先出(FIFO)。源代码是一使用数组实现队列,对队列的三个操作时间复杂度都是常量O(1)。

#include <stdio.h>
#include <stdlib.h>

#define QUEUESIZE 1000

typedef struct
{
    int head, tail;
    size_t length;
    int items[QUEUESIZE]
} QUEUE;

void enqueue(QUEUE *, int);
int dequeue(QUEUE *);

main()
{
    int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    QUEUE* q;
    int i;

    q = (QUEUE *)malloc(sizeof(QUEUE));
    q->head = q->tail = 0;
    q->length = 0;
    printf("The original number of elements in queue is:\n\t%d\n", q->length);
    for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
        enqueue(q, arr[i]);
    printf("The number of elements in queue after enqueuing is:\n\t%d\n", q->length);
    printf("The elements in queue is:\n\t");
    while(!isEmpty(q))
        printf("%d ", dequeue(q));
    printf("\nThe number of elements  in queue after dequeuing is:\n\t%d\n", q->length);
    return 0;
}

int isEmpty(QUEUE *q)
{
    if (q->length == 0)
        return 1;
    else
        return 0;
}

void enqueue(QUEUE *q, int x)
{
    if (q->length == QUEUESIZE - 1)
        fputs("Error: queue overflow\n", stderr);
    else {
        q->items[q->tail] = x;
        if (q->tail == QUEUESIZE - 1)
            q->tail = 0;
        else
            q->tail += 1;
        q->length += 1;
        return;
    }
}

int dequeue(QUEUE *q)
{
    if (q->length == 0)
        fputs("Error: queue underflow\n", stderr);
    else {
        int x;
        x = q->items[q->head];
        if (q->head == QUEUESIZE - 1)
            q->head = 0;
        else
            q->head += 1;
        q->length -= 1;
        return x;
    }
}


5.链接链表

源代码实现了一个双向链表,定义了三个操作包括搜索在链表中第一次出现的关键字,并返回其结点指针;向链表中插入一个结点;从链表中删除一个结点。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ARRAYSIZE 1000

typedef struct node
{
    int key;
    struct node *next, *prev;
}NODE;

typedef struct list
{
    NODE *head;

}LIST;

NODE *listSearch(LIST *, int);
void listInsert(LIST *, NODE *);
void listDelete(LIST *, NODE *);

main()
{
    LIST *L;
    NODE *x, *temp;
    int len, n, i, r;
    int arr[ARRAYSIZE];

    len = 0;
    L = (LIST *)malloc(sizeof(LIST));
    printf("Enter elements: ");
    while (len < ARRAYSIZE && scanf("%d", &n) > 0)
        arr[len++] = n;
    L->head = NULL;
    printf("The elements in nitial list are:\n\t");
    for (x = L->head; x; x = x->next)
       printf("%d\t", x->key);
    for (i = 0; i < len; i++) {
        x = (NODE *)malloc(sizeof(NODE));
        x->key = arr[i];
        x->next = NULL;
        x->prev = NULL;
        listInsert(L, x);
        x = x->next;
    }
    printf("\nThe elements in inseted list  are:\n\t");
    for (x = L->head; x; x = x->next)
       printf("%d ", x->key);
    srand(time(NULL));
    r = rand() % len;
    printf("\nGenerating random index between 0 and (len-1) is:\n\t%d\n", r);
    printf("Node acquried by searching, the key of which is:\n\t%d\n", listSearch(L, arr[r])->key);
    if (listSearch(L, arr[r])->prev)
        printf("Node acquried by searching, the key of previous node of which is:\n\t%d\n", listSearch(L, arr[r])->prev->key);
    if (listSearch(L, arr[r])->next)
        printf("Node acquried by searching, the key of next node of which is:\n\t%d\n", listSearch(L, arr[r])->next->key);
    printf("Loop calling list deleting:\n");
    x = L->head;
    i = 0;
    while (x) {
        listDelete(L, x);
        printf("\tThe elements in list after %d times deleting: ", ++i);
        for (temp = L->head; temp; temp = temp->next)
            printf("%d ", temp->key);
        printf("\n");
        temp = x;
        x = x->next;
        free(temp);
    }
    free(L);
    return 0;
}

NODE *listSearch(LIST *L, int k)
{
    NODE *x;
    x = L->head;
    while (x != NULL && x->key != k)
        x = x->next;
    return x;
}

void listInsert(LIST *L, NODE *x)
{
    x->next = L->head;
    if (L->head != NULL)
        L->head->prev = x;
    L->head = x;
    x->prev = NULL;
    return;
}

void listDelete(LIST *L, NODE *x)
{
    if (x->prev != NULL)
        x->prev->next = x->next;
    else
        L->head = x->next;
    if (x->next != NULL)
        x->next->prev = x->prev;
    return;
}

6.对象

源代码使用多维数组实现双链表,包括数组的初始化和申请对象、释放对象两个操作。

#include <stdio.h>
#include <stdlib.h>

#define OBJECTSIZE 10

static int fr, L;
typedef struct object
{
    int next, key, prev;
    int index;
} OBJECT;
OBJECT lis[OBJECTSIZE];

OBJECT allocateObject();
void freeObject(OBJECT);

main()
{
    int i, j, len, n, temp[OBJECTSIZE];
    OBJECT x;

    for (i = 0; i < OBJECTSIZE - 1; i++)
        lis[i].next = i + 1;
    lis[OBJECTSIZE - 1].next = -1;
    printf("The initial value of next member of object array:\n\t");
    for (i = 0; i < OBJECTSIZE; i++)
        printf("%d ", lis[i].next);
    printf("\n");
    fr = 0;
    L = -1;
    len = 0;
    i = 0;
    printf("Enter needed to insert elements:\n\t");
    while (len < OBJECTSIZE && scanf("%d", &n) > 0) {
        temp[i++] = n;
        len++;
    }
    for (i = 0; i < len; i++) {
        lis[i] = allocateObject();
        lis[i].key = temp[i];
        lis[i].prev = -1;
        lis[i].next = L;
        lis[i].index = i;
        lis[L].prev = i;
        L = lis[i].index;
    }
    j = L;
    printf("Output elements which have been inserted:\n\t");
    while (j+1) {
        printf("%d ", lis[j].key);
        j = lis[j].next;
    }
    printf("\n");
    printf("Free all allocated object:\n\t");
    for (i = len - 1; i >= 0; i--) {
        freeObject(lis[i]);
    }
    return 0;
}

OBJECT allocateObject()
{
    OBJECT x;
    if (fr == -1) {
        printf("Error: out of space", stderr);
        abort();
    }
    else {
        x.index = fr;
        fr = x.next;
        return x;
    }
}

void freeObject(OBJECT x)
{
    x.next = fr;
    fr = x.index;
}


7.二叉搜索树(binary search tree)简称二叉树

源代码实现了二叉树的结点插入,删除,前序、中序、后序和层序遍历,搜索给定键值的结点,计算最大最小值,计算结点的前继和后继结点。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SIZE 10
#define QUEUESIZE 1000

typedef struct node
{
    int key;
    struct node *left, *right, *p;
} NODE;
typedef struct tree
{
    NODE* root;
} TREE;
typedef struct queue
{
    int head, tail;
    size_t length;
    NODE *items[QUEUESIZE];
}QUEUE;

void treeinsert(TREE *, NODE *);
void inorder(NODE *);
void postorder(NODE *);
void preorder(NODE *);
NODE *treemin(NODE *);
NODE *treemax(NODE *);
NODE *treesearch(NODE *, int);
NODE *treesuccessor(NODE *);
NODE *treepredecessor(NODE *);
NODE *treesuccessor(NODE *);
void treedelete(TREE *, NODE *);
void levelorder(NODE *);
void enqueue(QUEUE *, NODE *);
NODE *dequeue(QUEUE *);

main()
{
    int r, i;
    TREE *tree;
    NODE *node;

    tree = (TREE *)malloc(sizeof(TREE));
    tree->root = NULL;
    i = 0;
    srand(time(NULL));
    printf("Generating random number will be inserted is:\n\t");
    while (i < SIZE) {
        r = rand() % 1000;
        node = (NODE *)malloc(sizeof(NODE));
        node->left = node->right = NULL;
        node->key = r;
        treeinsert(tree, node);
        i++;
        printf("%d ", r);
    }
    printf("\nThe result of inorder tree walk:\n\t");
    inorder(tree->root);

    printf("\nThe result of previous order tree walk:\n\t");
    preorder(tree->root);

    printf("\nThe result of post order tree walk:\n\t");
    postorder(tree->root);

    printf("\nThe result of level order tree walk:\n\t");
    levelorder(tree->root);
    printf("\n");

    node = treemin(tree->root);
    printf("The minimum key of the tree nodes is:\n\t%d\n", node->key);

    node = treemax(tree->root);
    printf("The maximum key of the tree nodes is:\n\t%d\n", node->key);

    node = treesearch(tree->root, r);
    printf("The key of node acquried by tree searching are:\n\t%d\n", node->key);

    node = treesuccessor(tree->root);
    printf("The key of tree node and successor node of which are respective:\n\t%d, %d\n",
          tree->root->key, node->key);

    node = treepredecessor(tree->root);
    printf("The key of predecessor node and tree node are respective:\n\t%d, %d\n",
           node->key, tree->root->key);

    treedelete(tree, tree->root);
    printf("The result of in order of tree walk after deleting the root of the tree is\n\t");
    inorder(tree->root);
    printf("\n");
    return 0;
}

void treeinsert(TREE *T, NODE *z)
{
    NODE *x, *y;

    x = (NODE *)malloc(sizeof(NODE));
    y = (NODE *)malloc(sizeof(NODE));
    y = NULL;
    x = T->root;
    while(x != NULL) {
        y = x;
        if (z->key < x->key)
            x = x->left;
        else
            x = x->right;
    }
    z->p = y;
    if (y == NULL)
        T->root = z;
    else if (z->key < y->key)
        y->left = z;
    else
        y->right = z;
    return;
}

void inorder(NODE *x)
{
    if (x != NULL) {
        inorder(x->left);
        printf("%d ", x->key);
        inorder(x->right);
    }
    return;
}

void preorder(NODE *x)
{
    if (x != NULL) {
        printf("%d ", x->key);
        preorder(x->left);
        preorder(x->right);
    }
    return;
}

void postorder(NODE *x)
{
    if (x != NULL) {
        postorder(x->left);
        postorder(x->right);
        printf("%d ", x->key);
    }
    return;
}

void levelorder(NODE *x)
{
    QUEUE *q;

    q = (QUEUE *)malloc(sizeof(QUEUE));
    q->length = 0;
    q->head = q->tail = 0;
    while (x != NULL) {
        printf("%d ", x->key);
        if (x->left)
            enqueue(q, x->left);
        if (x->right)
            enqueue(q, x->right);
        x = dequeue(q);
    }
    return;
}
NODE *treemin(NODE *x)
{
   while (x->left != NULL)
        x = x->left;
   return x;
}

NODE *treemax(NODE *x)
{
    while (x->right != NULL)
        x = x->right;
    return x;
}

NODE *treesearch(NODE *x, int k)
{
    while (x != NULL && x->key != k)
        if (k < x->key)
            x = x->left;
        else
            x = x->right;
    return x;
}

NODE *treesuccessor(NODE *x)
{
    NODE *y;

    y = (NODE *)malloc(sizeof(NODE));
    if (x->right != NULL)
        return treemin(x->right);
    y = x->p;
    while(y != NULL && x == y->right) {
        x = y;
        y = y->p;
    }
    return y;
}

NODE *treepredecessor(NODE *x)
{
    NODE *y;

    y = (NODE *)malloc(sizeof(NODE));
    if (x->left != NULL)
        return treemax(x->left);
    y = x->p;
    while (y != NULL && x == y->left) {
        x = y;
        y = y->p;
    }
    return y;
}

void transplant(TREE *T, NODE *u, NODE *v)
{
     if (u->p == NULL)
        T->root = v;
    else if (u->p->left == u)
        u->p->left = v;
    else
        u->p->right = v;
    if (v != NULL)
        v->p = u->p;
    return;
}

void treedelete(TREE *T, NODE *z)
{
    NODE *y;

    y = (NODE *)malloc(sizeof(NODE));
    if (z->left == NULL)
        transplant(T, z, z->right);
    else if (z->right == NULL)
        transplant(T, z, z->left);
    else{
        y = treemin(z->right);
        if (y != z->p) {
            transplant(T, y, y->right);
            y->right = z->right;
            y->right->p = y;
        }
        transplant(T, z, y);
        y->left = z->left;
        y->left->p = y;
    }
    return;
}

/* Queue: enqueue */
void enqueue(QUEUE *q, NODE *x)
{
    if (q->length == QUEUESIZE - 1)
        fputs("Error: queue overflow", stderr);
    else {
        q->items[q->tail] = x;
        if (q->tail == QUEUESIZE - 1)
            q->tail = 0;
        else
            q->tail += 1;
        q->length += 1;
        return;
    }
}

/* dequeue */
NODE *dequeue(QUEUE *q)
{
    if (q->length == QUEUESIZE - 1)
        fputs("Error: queue underflow", stderr);
    else {
        NODE *x;
        x = q->items[q->head];
        if (q->head == QUEUESIZE - 1)
            q->head = 0;
        else
            q->head += 1;
        q->length -= 1;
        return x;
    }
}


8.红黑树(Red-Black Tree)又称平衡二叉树

是一个高度平衡二叉树,在插入和删除时维护红黑性质:包括5个红黑性质:

树的根结点是黑色的;

结点的颜色是红色或者黑色;

每个红结点有两个黑孩子;

所有的叶结点都是黑色的;

从每个结点沿着一条路径到其后继叶结点包含的黑结点数量相同;

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct treenode
{
    int key;
    struct treenode *left, *right, *p;
    char color;
} TREENODE;

typedef struct tree
{
    TREENODE *nil, *root;
} TREE;

void leftrotate(TREE *, TREENODE *);
void rightrotate(TREE *, TREENODE *);
void rbinsert(TREE *, TREENODE *);
void rbinsertfixup(TREE *, TREENODE *);
void inorder(TREE *, TREENODE *);
void rbtransplant(TREE *, TREENODE *, TREENODE *);
TREENODE *rbmin(TREE *, TREENODE *);
void rbdelete(TREE *, TREENODE *);
void rbdeletefixup(TREE *, TREENODE *);

main()
{
    TREE *T;
    int r, i;
    TREENODE *node;

    T = (TREE *)malloc(sizeof(TREE));
    T->nil = (TREENODE *)malloc(sizeof(TREENODE));
    T->root = (TREENODE *)malloc(sizeof(TREENODE));
    T->nil->key = 0;
    T->nil->left = NULL;
    T->nil->right = NULL;
    T->nil->p = NULL;
    T->nil->color = 'b';
    T->root = T->nil;
    srand(time(NULL));
    printf("The key-color pairs after red black tree insert:\n");
    for (i = 0; i < 10; i++) {
        node = (TREENODE *)malloc(sizeof(TREENODE));
        r = rand() % 1000;
        node->key = r;
        rbinsert(T, node);
        printf("\t{key = %d, color = %c}\n", node->key, node->color);
    }
    //inorder traverse after inserting
    printf("\nThe key-value pairs of inorder traverse in red black tree:\n");
    inorder(T, T->root);
    printf("The original key-color of tree root:\n\t{%d, %c}\n",
           T->root->key, T->root->color);
    if (T->root->left != T->nil)
        printf("The original key-color of left child of tree root:\n\t{%d, %c}\n",
               T->root->left->key, T->root->left->color);
    if (T->root->right != T->nil)
        printf("The original key-color of right child of tree root:\n\t{%d, %c}\n",
               T->root->right->key, T->root->right->color);
    //Delete tree nodes of red black tree
    rbdelete(T, T->root);
    printf("\nThe key-value pairs of inorder traverse after delete tree root:\n");
    inorder(T, T->root);
    printf("The key-color of tree root after deleting:\n\t{%d, %c}\n",
           T->root->key, T->root->color);
    if (T->root->left != T->nil)
        printf("The okey-color of left child of tree root after deleting:\n\t{%d, %c}\n",
               T->root->left->key, T->root->left->color);
    if (T->root->right != T->nil)
        printf("The key-color of right child of tree root after deleting:\n\t{%d, %c}\n",
               T->root->right->key, T->root->right->color);

    free(node);
    free(T->root);
    free(T->nil);
    free(T);
    return 0;
}

void leftrotate(TREE *T, TREENODE *x)
{
    TREENODE* y;

    y = x->right;
    x->right = y->left;
    if (y->left != T->nil)
        y->left->p = x;
    y->p = x->p;
    if (x->p == T->nil)
        T->root = y;
    else {
        if (x == x->p->left)
            x->p->left = y;
        else
            x->p->right = y;
    }
    y->left = x;
    x->p = y;
    return;
}

void rightrotate(TREE *T, TREENODE *x)
{
    TREENODE *y;

    y = x->left;
    x->left = y->right;
    if (y->right != T->nil)
        y->right->p = x;
    y->p = x->p;
    if (x->p == T->nil)
        T->root = y;
    else {
        if (x == x->p->left)
            x->p->left = y;
        else
            x->p->right = y;
    }
    y->right = x;
    x->p = y;
    return;
}

void rbinsert(TREE *T, TREENODE *z)
{
    TREENODE *x, *y;

    y = T->nil;
    x = T->root;
    while (x != T->nil) {
        y = x;
        if (z->key < x->key)
            x = x->left;
        else
            x = x->right;
    }
    if (y == T->nil)
         T->root = z;
    else {
        if (z->key < y->key)
            y->left = z;
        else
            y->right = z;
    }
    z->p = y;
    z->left = T->nil;
    z->right = T->nil;
    z->color = 'r';
    rbinsertfixup(T, z);
    return;
}

void rbinsertfixup(TREE *T, TREENODE *z)
{
    TREENODE *y;

    while (z->p->color == 'r') {
        if (z->p->p->left == z->p) {
            y = z->p->p->right;
            if (y->color == 'r') {
                z->p->color = 'b';
                y->color = 'b';
                z->p->p->color = 'r';
                z = z->p->p;
            }
            else {
                if (z == z->p->right) {
                    z = z->p;
                    leftrotate(T, z);
                }
                z->p->color = 'b';
                z->p->p->color = 'r';
                rightrotate(T, z->p->p);
            }
        }
        else {
            y = z->p->p->left;
            if (y->color == 'r') {
                z->p->color = 'b';
                y->color = 'b';
                z->p->p->color = 'r';
                z = z->p->p;
            }
            else {
                if (z == z->p->left) {
                    z = z->p;
                    rightrotate(T, z);
                }
                z->p->color = 'b';
                z->p->p->color = 'r';
                leftrotate(T, z->p->p);
            }
        }
    }
    T->root->color = 'b';
    return;
}

void inorder(TREE *T, TREENODE *x)
{
    if (x != T->nil) {
        inorder(T, x->left);
        printf("\t{key = %d, color = %c}\n", x->key, x->color);
        inorder(T, x->right);
    }
    return;
}

void rbtransplant(TREE *T, TREENODE *u, TREENODE *v)
{
    if (u->p == T->nil)
        v = T->root;
    else {
        if (u == u->p->left)
            u->p->left = v;
        else
            u->p->right = v;
    }
    v->p = u->p;
    return;
}

TREENODE *rbmin(TREE *T, TREENODE *x)
{

    if (x != T->nil)
        x = x->left;
    return x;
}

void rbdelete(TREE *T, TREENODE *z)
{
    TREENODE *y, *x;
    char yorcolor;

    y = z;
    yorcolor = y->color;
    if (z->left == T->nil) {
        x = z->right;
        rbtransplant(T, z, z->right);
    }
    else{
        if (z->right == T->nil) {
            x = z->left;
            rbtransplant(T, z, z->left);
        }
        else {
            y = rbmin(T, z->right);
            yorcolor = y->color;
            x = y->right;
            if (y->p == z)
                x->p = y;
            else {
                rbtransplant(T, y, y->right);
                y->right = z->right;
                y->right->p = y;
            }
            rbtransplant(T, z, y);
            y->left = z->left;
            y->left->p = y;
            y->color = z->color;
        }
    }
    if (yorcolor == 'b')
        rbdeletefixup(T, x);
    return;
}

void rbdeletefixup(TREE *T, TREENODE *x)
{
    while (x != T->root && x->color == 'b') {
        TREENODE *w;

        if (x == x->p->left) {
            w = x->p->right;
            if (w->color == 'r') {
                w->color = 'b';
                x->p->color = 'r';
                leftrotate(T, x->p);
                w = x->p->right;
            }
            if (w->left->color == 'b' && w->right->color == 'b') {
                w->color = 'r';
                x = x->p;
            }
            else {
                if (w->right->color == 'b') {
                    w->color = 'r';
                    w->left->color = 'b';
                    rightrotate(T, w);
                    w = x->p->right;
                }
                w->right->color = 'b';
                w->color = x->p->color;
                x->p->color = 'b';
                leftrotate(T, x->p);
                x = T->root;
            }
        }
        else {
            w = x->p->left;
            if (w->color == 'r') {
                w->color = 'b';
                x->p->color = 'r';
                rightrotate(T, x->p);
                w = x->p->left;
            }
            if (w->right->color == 'b' && w->right->color == 'b') {
                w->color = 'r';
                x = x->p;
            }
            else {
                if (w->left->color == 'b') {
                    w->color = 'r';
                    w->right->color == 'b';
                    leftrotate(T, w);
                    w = x->p->left;
                }
                w->left->color = 'b';
                w->color = x->p->color;
                x->p->color = 'b';
                rightrotate(T, x->p);
                x = T->root;
            }
        }
    }
    x->color = 'b';
    return;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值