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

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);//向后移动frwd
int *list_prv(LIST* list);//向前移动frwd
int *list_current(LIST* list);//返回frwd
int 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;
}//向后移动frwd

int* list_prev(LIST* list){
    int* data = &list->frwd->data;
    list->frwd = list->frwd->prev;
    return data;
}//向前移动frwd

int* list_current(LIST* list){
    return &list->frwd->data;
}//返回frwd

int 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));
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值