C和指针 第十七章 经典数据类型 堆栈 队列 二叉树

堆栈:

//
// Created by mao on 16-9-16.
//

#ifndef UNTITLED_STACK_H
#define UNTITLED_STACK_H
#define TRUE 1
#define FALSE 0

typedef int STACK_TYPE;
typedef struct stack{
    STACK_TYPE value;
    struct stack *next;
} STACK;

void create_stack();
void destory_stack();
void push(STACK_TYPE value);
STACK_TYPE pop();
int isEmpty();
#endif //UNTITLED_STACK_H

stack.h

//
// Created by mao on 16-9-16.
//
#include <stdlib.h>
#include "stack.h"

static STACK *stack;

void create_stack()
{
    stack = (STACK *)malloc(sizeof(STACK));
    stack -> next = NULL;
}

void destory_stack()
{
    STACK *pStack;
    while((pStack = stack -> next) != NULL){
        free(stack);
        stack = pStack;
    }
}

void push(STACK_TYPE value)
{
    STACK *new = (STACK *)malloc(sizeof(STACK));
    new -> next = stack;
    new -> value = value;
    stack = new;
}

STACK_TYPE pop()
{
    STACK_TYPE value = stack -> value;
    STACK *pStack = stack;
    stack = stack -> next;
    free(pStack);
    return value;
}

int isEmpty()
{
    return stack -> next == NULL ? TRUE : FALSE;
}

stack.c

#include <stdio.h>
#include "stack.h"

int main()
{
    //堆栈
    create_stack();
    push(10);
    push(20);
    push(30);
    pop();
    push(22);
    while(isEmpty() == FALSE){
        printf("%d \t", pop());
    }
}

main.c

运行:

队列:

当使用数组作为队列时,如果只是一端插入一端弹出,那么当尾部没有空间时,便无法插入元素,一种解决方法是使用“环绕”数组,新元素可以存储到以前删除元素所留出来的空间中,这种方法称为循环数组。

循环数组有个问题,当队列为空,或者为满时,首位的下标是一样的,无法判断出此时队列的状态,所以在队列的rear后加一个空余的不使用的位置,用来判断队列的状态是满队列,还是空队列。

当为满队列时:

(rear + 2) % QUEUE_SIZE  = front

当为空队列时:

(rear + 1) % QUEUE_SIZE = front

队列实现:

//
// Created by mao on 16-9-16.
//

#ifndef UNTITLED_QUEUE_H
#define UNTITLED_QUEUE_H
#define TRUE  1
#define FALSE 0
#define QUEUE_SIZE 100
#define ARRAY_SIZE (QUEUE_SIZE + 1)
typedef int QUEUE_TYPE;

static QUEUE_TYPE queue[ARRAY_SIZE];
static int front = 1;
static int rear = 0;

void Q_delete();
QUEUE_TYPE Q_first();
void Q_insert(QUEUE_TYPE value);
int Q_isEmpty();
int Q_isFull();
#endif //UNTITLED_QUEUE_H

queue.h

//
// Created by mao on 16-9-16.
//

#include "queue.h"
#include <assert.h>

void Q_delete()
{
    assert(Q_isEmpty() == FALSE);
    front = (front + 1) % QUEUE_SIZE;
    front = (front) % QUEUE_SIZE;
}

QUEUE_TYPE Q_first()
{
    assert(Q_isEmpty() == FALSE);
    return queue[front];
}

//队列插入数据,rear++
void Q_insert(QUEUE_TYPE value)
{
    assert(Q_isFull() == FALSE);
    rear = (rear + 1) % QUEUE_SIZE;
    queue[(rear) % QUEUE_SIZE] = value;
}

int Q_isEmpty()
{
    return (rear + 1) % QUEUE_SIZE == front ? TRUE: FALSE;
}

int Q_isFull()
{
    return (rear + 2) % QUEUE_SIZE == front ? TRUE : FALSE;
}

queue.c

#include <stdio.h>
#include "queue.h"

int main()
{

    //插入队列
    Q_insert(10);
    Q_insert(12);
    Q_delete();
    Q_insert(22);
    Q_insert(30);
    printf("%d\n", Q_first());
    Q_delete();
    printf("%d\n", Q_first());
    Q_delete();
    printf("%d\n", Q_first());
    Q_delete();


    return 1;
}

main.c

运行:

二叉树:

 

#ifndef UNTITLED_BINARYTREE_H
#define UNTITLED_BINARYTREE_H

#include <assert.h>
#define TREE_TYPE int
#define ARRAY_SIZE 100
#define TREE_SIZE (ARRAY_SIZE + 1)
TREE_TYPE TREE[TREE_SIZE] = {0};

static unsigned int leftChild(unsigned int current)
{
    return current * 2;
}

static unsigned int rightChild(unsigned int current)
{
    return current * 2 + 1;
}

void insert(TREE_TYPE value)
{
    unsigned int current = 1;
    while(TREE[current] != 0){
        if(value < TREE[current]){
            current = leftChild(current);
        }else{
            assert(TREE[current] != value);
            current = rightChild(current);
        }
        assert(current < TREE_SIZE);
    }
    TREE[current] = value;
}

TREE_TYPE *find(TREE_TYPE value)
{
    unsigned int current = 1;
    while (current < TREE_SIZE && TREE[current] != value){
        if(value < TREE[current]){
            current = leftChild(current);
        }else if(value > TREE[current]){
            current = rightChild(current);
        }
    }
    if(current < TREE_SIZE){
        return TREE + current;
    }else{
        return 0;
    }
}

//根据指针计算数组下标
static unsigned long getIndex(TREE_TYPE *ptr){
    assert(ptr >= TREE || ptr <= TREE + TREE_SIZE);
    return ptr - TREE;
}

//内置先遍历接口
void pre_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
{
    if(current < ARRAY_SIZE && TREE[current] != 0){
        callback(TREE[current]);
        pre_order_traverse(leftChild(current), callback);
        pre_order_traverse(rightChild(current), callback);
    }
}

//先序遍历
void do_pre_traverse(void(*callback)(TREE_TYPE value))
{
    pre_order_traverse(1, callback);
}
//中序遍历
void mid_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
{
    if(current < ARRAY_SIZE && TREE[current] != 0){
        mid_order_traverse(leftChild(current), callback);
        callback(TREE[current]);
        mid_order_traverse(rightChild(current), callback);
    }
}

void do_mid_order_traverse(void(*callback)(TREE_TYPE value))
{
    mid_order_traverse(1, callback);
}

//后续遍历
void after_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
{
    if(current < ARRAY_SIZE && TREE[current] != 0){
        after_order_traverse(leftChild(current), callback);
        after_order_traverse(rightChild(current), callback);
        callback(TREE[current]);
    }
}

void do_after_order_traverse(void(*callback)(TREE_TYPE value))
{
    after_order_traverse(1, callback);
}

void print_tree(TREE_TYPE value)
{
    printf("%d\t", value);
}

#endif //UNTITLED_BINARYTREE_H

BinaryTree.h

#include <stdio.h>
#include "BinaryTree.h"

int main()
{
    insert(20);
    insert(12);
    insert(5);
    insert(9);
    insert(16);
    insert(17);
    insert(25);
    insert(28);
    insert(26);
    insert(29);

    do_pre_traverse(print_tree);
    printf("\n");
    do_mid_order_traverse(print_tree);
    printf("\n");
    do_after_order_traverse(print_tree);
    return 1;
}

main.c

运行:

数组形式存放二叉树,会导致内存空间的浪费,尤其是非对称的二叉树,会造成大量的数组空间闲置。通过链式二叉树可以解决数组不充分的问题

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

typedef int TREE_TYPE;
typedef struct TREE_NODE {
    TREE_TYPE value;
    struct TREE_NODE *leftPtr;
    struct TREE_NODE *rightPtr;
} TREE_NODE;
//指向树的根节点的指针
TREE_NODE *root;

//创建根节点
void createTree(TREE_TYPE value)
{
    root = (TREE_NODE *) malloc(sizeof(TREE_NODE));
    root -> leftPtr = NULL;
    root -> rightPtr = NULL;
    root -> value = value;
}

TREE_NODE * getRoot()
{
    return root;
}

//插入节点
void insertNode(TREE_TYPE value)
{
    TREE_NODE *current = root;
    //pos为待插入节点的父节点
    TREE_NODE *parent = root;
    while(current != NULL){
        //保存父节点信息
        parent = current;
        if(current -> value < value){
            current = current -> rightPtr;
        }else if(current -> value > value){
            current = current -> leftPtr;
        }else{
            //节点已存在
            return ;
        }
    }
    TREE_NODE *node = (TREE_NODE *) malloc(sizeof(TREE_NODE));
    assert(node != NULL);
    node -> leftPtr = NULL;
    node -> rightPtr = NULL;
    node -> value = value;
    //根据值得大小判断,node应该放在左节点还是右节点
    if(parent -> value > value){
        parent -> leftPtr = node;
    }else{
        parent -> rightPtr = node;
    }
}

TREE_NODE * findNode(TREE_TYPE value)
{
    TREE_NODE *current = root;
    while(current != NULL && current -> value != value){
        if( current -> value > value){
            current = current -> leftPtr;
        }else{
            current = current -> rightPtr;
        }
    }
    return current;
}

void printNode(TREE_NODE * node)
{
    printf("%d\t", node -> value);
}

void pre_order_traverse(TREE_NODE * current)
{
    if(current != NULL){
        printNode(current);
        pre_order_traverse(current -> leftPtr);
        pre_order_traverse(current -> rightPtr);
    }
}

void mid_order_traverse(TREE_NODE * current)
{
    if(current != NULL){
        mid_order_traverse(current -> leftPtr);
        printNode(current);
        mid_order_traverse(current -> rightPtr);
    }
}

void after_order_traverse(TREE_NODE * current)
{
    if(current != NULL){
        after_order_traverse(current -> leftPtr);
        after_order_traverse(current -> rightPtr);
        printNode(current);
    }
}

BinaryTree.h

#include <stdio.h>
#include "BinaryTree.h"

int main()
{
	createTree(20);
	insertNode(12);
	insertNode(5);
	insertNode(9);
	insertNode(16);
	insertNode(17);
	insertNode(25);
	insertNode(28);
	insertNode(26);
	insertNode(29);
	
	pre_order_traverse(root);
	printf("\n");
	mid_order_traverse(root);
	printf("\n");
	after_order_traverse(root);

    return 1;
}

BinaryTree.c

运行:

 

posted @ 2016-09-17 08:40  xnuwu  阅读(286)  评论(0编辑  收藏  举报