数据结构(5)—— 链表、二叉树代码重构实现

来源:互联网 发布:mac terminal 指令 编辑:程序博客网 时间:2024/06/03 20:43

3 链表

3.1 双向链表

#ifndef _LS_H#define _LS_H#include <sys/types.h>typedef struct ListNode{    int data;    struct ListNode* next;    struct ListNode* prv;}LIST_NODE;typedef struct List{    LIST_NODE* head;    LIST_NODE* tail;    LIST_NODE* frwd;    LIST_NODE* bkwd;}LIST;void list_init(LIST* list);void list_deinit(LIST* list);int list_empty(LIST* list);void list_append(LIST* list,int data);//追加int list_insert(LIST* list,size_t pos,int data);int list_erase(LIST* list,size_t pos);//按位置删除void list_remove(LIST* list,int data);//按数据删除void list_clear(LIST* list);//全部删除数据int *list_at(LIST* list,size_t pos);//按位置取数据size_t list_size(LIST* list);//元素数量void list_begin(LIST* list);//开始正向迭代int *list_next(LIST* list);//向后移动frwdint *list_prv(LIST* list);//向前移动frwdint *list_current(LIST* list);//返回frwdint list_end(LIST* list);//判断正向迭代结束#endif
#include <stdio.h>#include "ls.h"//新建和销毁节点函数static LIST_NODE* create_node(int data,LIST_NODE* next,LIST_NODE* prev){    LIST_NODE* node = malloc(sizeof(LIST_NODE));    node->data = data;    node->next = next;    node->prev = prev;    return node;}static LIST_NODE* destroy_node(LIST_NODE* node,LIST_NODE* prev){//prev带回上一个节点的指针    LIST_NODE* next = node->next;    if (prev)        *prev = node->prev;//带出前节点    free(node);    return next;}//创建链表和销毁链表void list_init(LIST* list){    list->head = NULL;    list->tail = NULL;}void list_deinit(LIST* list){    while (list->head)        list->head = destroy_node(list->head,NULL);    list->tail = NULL;}int list_empty(LIST* list){    return !list->head && !list->tail;}//判断是否为空void list_append(LIST* list,int data){    list->tail = create_node(data,NULL,list->tail);    if (list->tail->prev)//如果前节点不为空,非空链表        list->tail->prev->next = list->tail;    else        list->head = list->tail;//原来是空链表}//追加int list_insert(LIST* list,size_t pos,int data){    LIST_NODE* find = list->head;    for (;find;find = find->next){        if (!pos--){            LIST_NODE* node = create_node(data,find,find->prev);            if (node->prev)//不为空,有前节点                node->prev->next = node;            else                list->head = node;//为空,没有前节点            node->next->prev = node;//改后节点的prev            return 1;//插入成功        }    }    return 0;//插入失败}int list_erase(LIST* list,size_t pos){    LIST_NODE* find = list->head;    for (;find;find = find->next){        if (!pos--){            LIST_NODE* prev = NULL;            LIST_NODE* next = destroy_node(find,&prev);            if (prev)//非首节点                prev->next = next;            else                list->head = next;            if (next)                next->prev = prev;//非尾节点            else                list->tail = prev;            return 1;        }    }    return 0;}void list_remove(LIST* list,int data){    LIST_NODE* find = list->head;    LIST_NODE* next = NULL;//记录下一个节点    for (;find;find = next){        //如果找到第一个数据,find节点被销毁        next = find-> next;//可以销毁find,不影响循环        if (find->data == data){            LIST_NODE* prev = NULL;            LIST_NODE* next = destroy_node(find,&prev);            if (prev)                prev->next = next;            else                list->head = next;            if (next)                next->prev = prev;            else                list->tail = prev;        }    }}void list_clear(LIST* list){    list_deinit(list);}//全部删除数据int* list_at(LIST* list,size_t pos){    LIST_NODE* find = list->head;    for (;find;find = find->next){        if (!pos--)            return &find->data;    }    return NULL;//没有找到,返回}//按位置取数据size_t list_size(LIST* list){    size_t size = 0;    LIST_NODE* find = list->head;    for (;find;find = find->next)        size++;    return size;}//元素数量void list_begin(LIST* list){    list->frwd = list->head;}//开始正向迭代int* list_next(LIST* list){    int* data = &list->frwd->data;    list->frwd = list->frwd->next;    return data;}//向后移动frwdint* list_prev(LIST* list){    int* data = &list->frwd->data;    list->frwd = list->frwd->prev;    return data;}//向前移动frwdint* list_current(LIST* list){    return &list->frwd->data;}//返回frwdint list_end(LIST* list){    return !list->frwd;}//判断正向迭代结束
#include <stdio.h>#include "ls.h"int main(){    LIST list;    list_init(&list);    list_append(&list,10);    list_append(&list,30);    list_append(&list,50);    list_insert(&list,1,20);    list_insert(&list,3,40);    list_begin(&list);    while (!list_end(&list))        printf("%d\n",*list_next(&list));    list_erase(&list,1);    list_append(&list,40);    list_remove(&list,40);    list_begin(&list);    while (!list_end(&list))        printf("%d\n",*list_next(&list));    list_deinit(&list);}

3.2 单向链表

#include <stdio.h>#include <stdlib.h>typedef struct ListNode{    int data;    struct ListNode* next;}LIST_NODE;//链表节点结构体typedef struct List{    LIST_NODE* head;    LIST_NODE* tail;}LIST;//链表结构体//创建链表节点static LIST_NODE* create_node(int data){    LIST_NODE* node = malloc(sizeof(LIST_NODE));    node->data = data;    node->next = NULL;    return node;}//销毁链表节点static LIST_NODE* destroy_node(LIST_NODE* node){    LIST_NODE* next = node->next;    free(node);    return next;}//初始化链表void list_init(LIST* list){    list->head = NULL;    list->tail = NULL;}//销毁链表void list_deinit(LIST* list){    while (list->head)        list->head = destroy_node(list->head);    list->tail = NULL;}//链表追加节点void list_append(LIST* list,int data){    LIST_NODE* node = create_node(data);    if (list->tail)        list->tail->next = node;    else        list->head = node;    list->tail = node;}//获取链表节点数size_t list_size(LIST* list){    size_t size = 0;    LIST_NODE* find = list->head;    for (;find;find = find->next)        size++;    return size;}//打印链表void list_print(LIST* list){    LIST_NODE* find = list->head;    for (;find;find = find->next)        printf("%-4d",find->data);    printf("\n");}//反向打印链表void rprint(LIST_NODE* head){    if (head){        rprint(head->next);        printf("%-4d",head->data);    }    return;}void list_rprint(LIST* list){    rprint(list->head);    printf("\n");}//反转链表void reverse(LIST_NODE* head){    if (head && head->next){        reverse(head->next);        head->next->next = head;        head->next = NULL;    }}void list_reverse(LIST* list){    reverse(list->head);    LIST_NODE* temp = list->head;    list->head = list->tail;    list->tail = temp;}//获取链表中间值int list_mid(LIST* list){    LIST_NODE* mid = NULL,*node = NULL;    for (mid = node = list->head;        node->next && node->next->next;        node = node->next-next,mid = mid->next);    return mid->data;}int main(){    LIST list;    list_init(&list);    list_append(&list,1);    list_append(&list,2);    list_append(&list,3);    list_print(&list);    list_rprint(&list);    list_reverse(&list);    list_print(&list);    printf("mid = %d\n",list_mid(&list));    list_deinit(&list);}

4 二叉树

/*有序二叉树*/#ifndef __BT_H#define __BT_H#include <sys/types.h>typedef struct BsTreeNode{//二叉链表节点    int data;    struct BsTreeNode* left;    struct BsTreeNode* right;}BSTREE_NODE;typedef struct BsTree{    BSTREE_NODE* root;    size_t size;}BSTREE;void bstree_init(BSTREE* bstree);void bstree_deinit(BSTREE* bstree);void bstree_insert(BSTREE* bstree,int data);int bstree_erase(BSTREE* bstree,int data);//删除void bstree_clear(BSTREE* bstree);//清空void bstree_update(BSTREE* bstree,int old,int new);int bstree_exit(BSTREE* bstree,int data);//查询是否存在void bstree_travel(BSTREE* bstree);//中序遍历size_t bstree_size(BSTREE* bstree);//数量size_t bstree_height(BSTREE* bstree);//层数#endif
#include <stdio.h>#include <stdlib.h>#include "bt.h"static BSTREE_NODE* create_node(int data){    BSTREE_NODE* node = malloc(sizeof(BSTREE_NODE));    node->data = data;    node->left = NULL;    node->right = NULL;    return node;}static void destroy_node(BSTREE_NODE* node){    free(node);}static void clear(BSTREE_NODE** root){    if (*root){        clear(&(*root)->left);        clear(&(*root)->right);        destroy_node(*root);        *root = NULL;    }}static void insert(BSTREE_NODE* node,BSTREE_NODE** root){    if (!*root)        *root = node;//空节点直接放入    else if(node){        if (node->data < (*root)->data)            insert(node,&(*root)->left);        else            insert(node,&(*root)->right);    }}//返回不是对应节点,是对应节点的父节点中指向对应节点的指针地址(二级指针)static BSTREE_NODE** find(int data,BSTREE_NODE** root){    if (!*root)        return root;    else{        if (data == (*root)->data)            return root;        else if (data < (*root)->data)            return find(data,&(*root)->left);        else            return find(data,&(*root)->right);    }}void bstree_init(BSTREE* bstree){    bstree->root = NULL;    bstree->size = 0;}void bstree_deinit(BSTREE* bstree){    clear(&bstree->root);    bstree->size = 0;}void bstree_insert(BSTREE* bstree,int data){    insert(create_node(data),&bstree->root);    bstree->size++;}int bstree_erase(BSTREE* bstree,int data){    BSTREE_NODE** node = find(data,&bstree->root);    if (*node){//非空,找到啦    //删除步骤:1 左插入右 2 替换父节点 3 删除    insert((*node)->left,&(*node)->right);    BSTREE_NODE* temp = *node;    *node = (*node)->right;    destroy_node(temp);    bstree->size--;    return 1;//找到并删除    }    return 0;}//删除void bstree_clear(BSTREE* bstree){    bstree_deinit(bstree);}//清空void bstree_update(BSTREE* bstree,int old,int new){    while (bstree_erase(bstree,old))        bstree_insert(bstree,new);}//修改int bstree_exit(BSTREE* bstree,int data){    return *find(data,&bstree->root) != NULL;}//查询是否存在static void travel(BSTREE_NODE* root){    if (root){        travel(root->left);        printf("%d ",root->data);        travel(root->right);    }}void bstree_travel(BSTREE* bstree){    travel(bstree->root);    printf("\n");}//中序遍历size_t bstree_size(BSTREE* bstree){    return bstree->size;}//数量static size_t height(BSTREE_NODE* root){    if (root){        size_t left = height(root->left);        size_t right = height(root->right);        return (left > right ? left : right) + 1;    }    return 0;}size_t bstree_height(BSTREE* bstree){    return height(bstree->root);}//层数
#include <stdio.h>#include "bt.h"int main(){    BSTREE bstree;    bstree_init(&bstree);    bstree_insert(&bstree,50);    bstree_insert(&bstree,70);    bstree_insert(&bstree,20);    bstree_insert(&bstree,60);    bstree_insert(&bstree,40);    bstree_insert(&bstree,30);    bstree_insert(&bstree,10);    bstree_insert(&bstree,90);    bstree_insert(&bstree,80);    bstree_travel(&bstree);    printf("size = %d,height = %d\n",      bstree_size(&bstree),bstree_height(&bstree));    bstree_erase(&bstree,60);    bstree_travel(&bstree);    bstree_deinit(&bstree);    printf("size = %d,height = %d\n",      bstree_size(&bstree),bstree_height(&bstree));}
0 0
原创粉丝点击