数据结构算法练习

数据结构与算法

链表

顺序表

#include <stdio.h>
#define MAX_LEN 20

struct ARRAY_LIST{
    
    
    int index;
    int data[MAX_LEN];
};

void init(struct ARRAY_LIST *arr){
    
    

    if(NULL == arr){
    
    
        return;
    }
    arr->index = 0;

}

void add(struct ARRAY_LIST *arr,int value){
    
    

    if(arr->index == MAX_LEN){
    
    
        printf("顺序表已满,无法插入!\n");
        return;
    }
    arr->data[arr->index] = value;
    arr->index ++;

}

void out(struct ARRAY_LIST *arr){
    
    

    int i;
    i = 0;
    while (i < arr->index)
    {
    
    
        printf("%d\n",arr->data[i]);
        i++;
    }

}


int main(){
    
    

    struct ARRAY_LIST arr;

    init(&arr);

    add(&arr,1);
    add(&arr,2);
    add(&arr,3);
    add(&arr,4);

    out(&arr);
    
}

链表

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

struct LINKNODE
{
    
    
    int value;
    struct LINKNODE *next;
};

int headadd(struct LINKNODE *head,int value){
    
    

    struct LINKNODE *node;
    struct LINKNODE *p;

    p = head->next;
    node = malloc(sizeof(struct LINKNODE));
    node->value = value;
    head->next = node;
    node->next = p;

}

int out(struct LINKNODE *linklist){
    
    

    if(linklist == NULL){
    
    
        printf("链表为空");
        return 0;
    }

    struct LINKNODE *node;

    node = linklist->next;
    while (node!=NULL)
    {
    
    
        printf("%d\n",node->value);
        node = node->next;
    }

}

struct LINKNODE *init(struct LINKNODE *head){
    
    

    struct LINKNODE *p;

    p = malloc(sizeof(struct LINKNODE));
    if(p == NULL){
    
    
        printf("Fail to malloc memory!\n");
        return NULL;
    }

    head = p;
    p->next = NULL;
    
    return head;
}

int delete(struct LINKNODE **head){
    
    

    struct LINKNODE *p;

    while((*head) != NULL){
    
    

        p = *head;
        *head = (*head)->next;
        free(p);

    }

}

struct LINKNODE *add(struct LINKNODE *head,int value){
    
    

    struct LINKNODE *node;
    struct LINKNODE *p;

    node = malloc(sizeof(struct LINKNODE));
    node->value = value;
    node->next = NULL;

    p = head;
    while(p->next != NULL){
    
    
        p = p->next;
    }
    p->next = node;

    return head;

}

int add2(struct LINKNODE **head,int value){
    
    

    struct LINKNODE *node;
    struct LINKNODE *p;

    node = malloc(sizeof(struct LINKNODE));
    node->value = value;

    p = (*head)->next;
    (*head)->next = node;
    node->next = p;

}

int main(){
    
    

    struct LINKNODE *head;  //头结点

    head = init(head);
    printf("开始添加\n");
    // head = add(head,1);
    // head = add(head,2);
    // head = add(head,3);
    add2(&head,1);
    add2(&head,2);
    add2(&head,3);
    printf("添加完成\n");
    out(head);
    delete(&head);
    printf("释放完成\n");
    out(head);

}

链表实例

删除链表中奇数结点

/**
 * @file        t1.c
 * @brief       释放链表中奇数结点
 */
#include <stdio.h>
#include <stdlib.h>

struct LINKNODE{
    
    
    struct LINKNODE *next;
    int data;
};

void init(struct LINKNODE **head)
{
    
    
    *head = malloc(sizeof(struct LINKNODE));
    (*head)->next = NULL;
    (*head)->data = 0;
}

void add(struct LINKNODE *head,int data)
{
    
    
    struct LINKNODE *p;
    struct LINKNODE *node;
    
    p = head->next;
    node = malloc(sizeof(struct LINKNODE));
    node->data = data;
    head->next = node;
    node->next = p;
}

void delood(struct LINKNODE *head)
{
    
    
    struct LINKNODE *p;
    struct LINKNODE *pre;

    p = head->next;
    pre = head;

    while(p != NULL){
    
    
        if(p->data % 2 != 0){
    
    
            //释放
            printf("释放 %d\n",p->data);
            pre->next = p->next;
            free(p);
            p = NULL;
            p = pre;
        }
        pre = p;
        p = p->next;
    }
}

void show(struct LINKNODE *head)
{
    
    
    struct LINKNODE *p;

    if(head->next == NULL){
    
    
        printf("链表为空\n");
        return;
    }

    p = head->next;
    while(p != NULL){
    
    
        printf("data :%d\n",p->data);
        p = p->next;
    }
}

int main()
{
    
    
    struct LINKNODE *head;

    init(&head);
    printf("初始化完成\n");

    add(head,1);
    add(head,2);
    add(head,3);
    add(head,4);
    add(head,5);
    add(head,6);
    add(head,7);
    add(head,9);
    
    delood(head);

    show(head);

}

栈部分

顺序栈

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MaxSize 10
typedef struct arraystack
{
    
    
    int Data[MaxSize];   // 存储元素的数组
    int topIdx;       //栈顶指针
}Node;
//入栈
void push(struct arraystack *node,int value){
    
    
    node->Data[node->topIdx] = value;
    node->topIdx++;
}
//弹栈
void pop(Node node){
    
    
    node.topIdx--;
}
//栈展示
void show(Node node){
    
    
    int i;
    for(i = 0; i < node.topIdx; i++){
    
    
        printf("value: %d \n",node.Data[i]);
    }
}
//判断栈空      返回0为空  非0为不空
int stackempty(Node node){
    
    
    printf("node.topIdx:%d\n",node.topIdx);
    if(node.topIdx != 0){
    
    
        return 1;
    }
    return 0;
}
//判断栈满      返回0为满 非零为不满
int stackfull(Node node){
    
    
    if(node.topIdx != MaxSize){
    
    
        return 1;
    }
    return 0;
}
int main(){
    
    
    Node node;
    node.topIdx = 0;
    int value,j;
    int empty,full;
    int num;
    empty = stackempty(node);
    if(empty == 0){
    
    
        printf("栈空!\n");
    }else{
    
    
        printf("栈非空:%d\n",empty);
    }
    printf("开始键入个数:\n");
    scanf("%d",&num);
    for(j = 0; j < num;j++){
    
    
        full = stackfull(node);
        if(full == 0){
    
    
            printf("栈满!topindex为:%d\n",node.topIdx);
        }else{
    
    
            printf("请输入:");
            scanf("%d",&value);
            push(&node,value);
        }
    }
    empty = stackempty(node);
    if(empty != 0){
    
    
        printf("栈不空!\n");
    }

    show(node);
}

队列

顺序队列,一般写法,存在假溢出的问题

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MaxLen 20
typedef struct Query{
    
    
    int data[MaxLen];
    int front;
    int rear;
}*Q;
//初始化队列
void Init(Q query){
    
    
    query->front=0;
    query->rear=0;
}
//入队
int InQuery(Q query,int value){
    
    
    int ret = 0;

    if(query->rear == MaxLen){
    
    
        printf("队列满");
        ret = 1;
    }
    printf("入队:%d\n",value);
    query->data[query->rear++] = value;
error:
    return ret;
}
//出队
int OutQuery(Q query){
    
    
    int ret = 0;
    printf("出队数据:%d \n",query->data[query->front]);
    if(quer->rear == 0){
    
    
        printf("队列空!");
        ret = 1;
        goto error;
    }
    query->front ++;
error:
    return ret;
}
//输出
void Show(Q query){
    
    
    int i;
    for(i = query->front;i < query->rear; i++){
    
    
        printf("输出[%d]: %d \n",i,query->data[i]);
    }
}
int main(){
    
    
    struct Query query;
    Init(&query);
    InQuery(&query,1);    
    InQuery(&query,2);    
    InQuery(&query,3);    
    InQuery(&query,4);    
    InQuery(&query,5);
    printf("出队\n");    
    OutQuery(&query);
    Show(&query);
}

顺序循环队列

/**
 * @file        arrayquery.c
 * @brief       顺序队列
 *              队列,先进先出
 * @author      UncleBb
 * @version     0.0.0.1
 * @date        2021/08/19
 */
#include <stdio.h>
#define MAX_LEN 5

#ifndef TRUE
#define TRUE                        1U                          //真
#endif

#ifndef FALSE
#define FALSE                       0U                          //假
#endif

struct ARRAYQUERY{
    
    
    int data[MAX_LEN];
    int front;
    int rear;
};

//初始化
void init(struct ARRAYQUERY *query){
    
    

    query->front = 0;
    query->rear = 0;

}


//判断队满
int isFull(struct ARRAYQUERY *query){
    
    

    if((query->rear + 1) % MAX_LEN == query->front){
    
    

        printf("队满\n");
        return TRUE;

    }

    return FALSE;

}

//判断队空
int isEmpty(struct ARRAYQUERY *query){
    
    
    
    if(query->rear == query->front){
    
    

        printf("队列空\n");
        return TRUE;

    }

    return FALSE;
}

//入队
void in(struct ARRAYQUERY *query,int value){
    
    

    if(isFull(query)){
    
    
        return;
    }
    printf("入队数据:%d\n",value);
    query->data[query->rear] = value;
    query->rear=(query->rear+1)%MAX_LEN;//下标后移,若在最后则转至头部
}

//出队
void out(struct ARRAYQUERY *query){
    
    

    if(isEmpty(query)){
    
    
        return;
    }
    printf("出队数据:%d\n",query->data[query->front]);
    query->front = (query->front + 1) % MAX_LEN;

}

//打印
void show(struct ARRAYQUERY *query){
    
    

    int i;
    printf("\n--------------------------------------\n");
    printf("队列信息:\n");
    printf("query->front :%d\n",query->front);
    printf("query->rear :%d\n",query->rear);
    printf("MAX_LEN :%d\n",MAX_LEN);
    printf("--------------------------------------\n\n");

    if(isEmpty(query)){
    
    
        return;
    }
    
    i = query->front;
    while (i != query->rear)
    {
    
    
        printf("输出[%d] :%d\n",i,query->data[i]);
        i = (i + 1) % MAX_LEN;
    }

}

int main(){
    
    
    
    struct ARRAYQUERY query;

    init(&query);
    in(&query,1);
    in(&query,2);
    in(&query,3);
    in(&query,4);
    out(&query);
    out(&query);
    out(&query);
    out(&query);
    // show(&query);
    // out(&query);
    in(&query,5);
    in(&query,6);
    in(&query,7);
    in(&query,8);
    in(&query,9);
    // out(&query);
    // out(&query);

    printf("\n\n\n打印结果:\n");
    printf("======================================\n");
    show(&query);

}

链队

/**
 * @file        link.c
 * @brief       链队
 * @note        队空条件:front=rear=NULL
                队满条件:不考虑
                进队e操作:将包含e的节点插入到单链表表尾
                出队操作:删除单链表首数据节点 
                参考博文:https://blog.csdn.net/qq_16261421/article/details/105964365
                这篇讲的更加细致,使用带头结点的链表实现:https://blog.csdn.net/weixin_39628343/article/details/110443525
 * @author      LZl
 * @version     0.0.0.1
 * @date        2021/6/11
 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MaxLen 20
//节点数据结构
typedef struct QNode{
    
    
    int data;
    struct QNode *next;
}*N;
//front 为头结点,rear指向最后一个节点
typedef struct LinkQuery{
    
    
    N front;
    N rear;
}*LQ;
//初始化队列
void Init(LQ *lq){
    
    
    *lq = malloc(sizeof(struct LinkQuery));
    N head;
    head = malloc(sizeof(struct QNode));
    (*lq)->front = head;
    (*lq)->rear = NULL;
}
//入队:将包含e的节点插入到单链表表尾
int InQuery(LQ lq,int value){
    
    
    N node;
    node = malloc(sizeof(struct QNode));
    node->data = value;
    if (lq->rear == NULL){
    
    
        lq->front->next = node;
        lq->rear = node;
    }else{
    
    
        lq->rear->next = node;
        lq->rear = node;
    }
}
//判断队空
int IsEmpty(LQ lq){
    
    
    if(lq->rear == NULL){
    
    
        return 1;
    }
    return 0;
}
//出队
void OutQuery(LQ lq,int *data){
    
    
    N node;
    if(IsEmpty(lq)){
    
    
        printf("队空\n");
    }else{
    
    
        node = lq->front->next;
        *data = node->data;
        lq->front->next = node->next;
        free(node);
    }
}
//输出
void Show(LQ lq){
    
    
    N node;
    node = lq->front->next;
    if(IsEmpty(lq)){
    
    
        printf("队空\n");
    }
    while(node){
    
    
        printf("value: %d\n",node->data);
        node = node->next;
    }
}
//销毁
void Destroy(LQ lq){
    
    
    N node;
    node = lq->front;
    while(lq->front){
    
    
        node = lq->front->next;
        free(lq->front);
        lq->front = node;
    }
    free(lq);
}
//获取长度
int GetLen(LQ lq){
    
    
    int len = 0;
    N node;

    node = lq->front->next;
    while(node){
    
    
        node = node->next;
        len++;
    }
    return len;
}
int main(){
    
    
    LQ lq;
    int value;
    int len;

    Init(&lq);
    Show(lq);
    InQuery(lq,1);
    InQuery(lq,2);
    InQuery(lq,3);
    InQuery(lq,4);
    InQuery(lq,5);
    OutQuery(lq,&value);
    printf("出队数据:%d\n",value);
    Show(lq);
    len = GetLen(lq);
    printf("队列长度:%d\n",len);
    Destroy(lq);
    printf("销毁完成\n");
}

二叉排序树

/**
 * @file        bitree.c
 * @brief       二叉树
 *              
 * @author      UncleBb
 * @version     0.0.0.1
 * @date        2021/08/19
 */
#include <stdio.h>
#include <stdlib.h>

#define MAX_LEN 20
struct BITREE{
    
    
    int data;
    struct BITREE *left;
    struct BITREE *right;
};

struct BITREE *STACK[MAX_LEN];
int top = 0;

//初始化
void init(struct BITREE **node){
    
    

    struct BITREE *temp;

    temp = malloc(sizeof(struct BITREE));
    temp->left = NULL;
    temp->right = NULL;
    temp->data = 10;
    *node = temp;

}

//二叉排序树插入
int search_insert(struct BITREE **node,int value){
    
    

    struct BITREE *temp;

    if((*node) == NULL){
    
    
        temp = malloc(sizeof(struct BITREE));
        temp->left = NULL;
        temp->right = NULL;
        temp->data = value;
        *node = temp;
    }

    if((*node)->data > value){
    
    
        printf("向左子树添加 %d : %d\n",(*node)->data,value);
        search_insert(&(*node)->left,value);
    } else if ((*node)->data < value) {
    
    
        printf("向右子树添加 %d : %d\n",(*node)->data,value);
        search_insert(&(*node)->right,value); 
    }

}

//先序遍历,递归实现
void pre_print(struct BITREE *node){
    
    

    if(node != NULL){
    
    
        printf("value :%d \n",node->data);
    } else {
    
    
        printf("树空\n");
        return;
    }

    if(node->left != NULL){
    
    
        pre_print(node->left);
    }
    if(node->right != NULL){
    
    
        pre_print(node->right);
    }

}

//先序遍历,非递归
void pre_print2(struct BITREE *node){
    
    

    struct BITREE *p = node;
    struct BITREE *q;
    
    if(node == NULL){
    
    

        printf("树空\n");
        return;
        
    } else {
    
    
        do{
    
    

            printf("value :%d\n",p->data);
            q = p->right;

            if(q != NULL){
    
    
                STACK[top] = q;
                top++;
            }

            p = p->left;

            if(p == NULL){
    
    
                top--;
                p = STACK[top];
            }

        }while(p != NULL);
    }

}

//释放
void destroy(struct BITREE **node){
    
    

    struct BITREE *temp;
    temp = *node;

    free(*node);
    *node = NULL;
    if(temp->left != NULL){
    
    

        destroy(&(temp->left));

    }
    if(temp->right != NULL){
    
    

        destroy(&(temp->right));

    }

}

int main(){
    
    

    struct BITREE *root;

    init(&root);

    search_insert(&root,11);
    search_insert(&root,5);
    search_insert(&root,3);
    search_insert(&root,7);

    pre_print2(root);

    destroy(&root);

    pre_print2(root);

}

栈队列实例

判断回文字符串

/**
 * @file        t2.c
 * @brief       使用堆栈判断是否为回文字符串
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 256
typedef char ElemType;

//栈结构体
struct STACK{
    
    
    ElemType stack[MAX];
    int top;
};

//栈操作

//入栈
void push(struct STACK *node,ElemType value)
{
    
    
    node->stack[node->top] = value;
    node->top++;
}

//弹栈
ElemType pop(struct STACK *node)
{
    
    
    ElemType value;
    node->top--;
    value = node->stack[node->top];
    return value;
}

int main()
{
    
    
    struct STACK stack;
    ElemType value;
    char str[256] = "abcdasadcba";
    int size;
    int i;
    int verify = 1;//记录是否为回文  1是0否

    stack.top = 0;
    /**
     *      sizeof 计算的是分配空间的实际字节数
     *      strlen 计算的是空间中字符个数,不包括\0
     **/
    size = strlen(str);
    printf("strlen str :%d\n",size);
    printf("size 2 :%d\n",size%2);

    for(i = 0; i < size/2; i++){
    
    
        push(&stack,str[i]);
    }

    if(size%2 != 0){
    
    
        //奇数长度
        //一半减1入栈,比较另一半-1


        for(i = 0; i < size/2; i++){
    
    
            printf("%c \n",str[size/2 + i + 1]);
            if(pop(&stack) == str[size/2 + i +1]){
    
    

            } else {
    
    
                verify = 0;
            }
        }

    } else {
    
    
        //偶数长度

        for(i = 0; i < size/2; i++){
    
    
            printf("%c \n",str[size/2 + i]);
            if(pop(&stack) == str[size/2 + i]){
    
    

            } else {
    
    
                verify = 0;
            }
        }
    }

    if(verify == 1){
    
    
        printf(" %s 是回文字符串\n",str);
    } else {
    
    
        printf(" %s 不是回文字符串\n",str);
    }

}

二叉树层序遍历及判断叶子结点个数

/**
 * @file        t2.c
 * @brief       二叉树层序遍历查询叶子结点数量
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef TRUE
#define TRUE                        1U                          //真
#endif
#ifndef FALSE
#define FALSE                       0U                          //假
#endif
#define MAX 20

typedef int ElemType;

struct BiTree{
    
    
    struct BiTree *left;
    struct BiTree *right;
    ElemType data;
};

//队列结构体
struct BiTreeQueue{
    
    
    struct BiTree data[MAX];
    int front;
    int rear;
};

//初始化根节点
void init(struct BiTree **root)
{
    
    
    struct BiTree *p;

    p = malloc(sizeof(struct BiTree));
    p->left = NULL;
    p->right = NULL;
    p->data = 10;
    *root = p;
}

//向二叉排序树中添加结点(左小右大)
void add(struct BiTree **root,ElemType value)
{
    
    
    struct BiTree *p;

    if((*root) == NULL){
    
    
        p = malloc(sizeof(struct BiTree));
        p->left = NULL;
        p->right = NULL;
        p->data = value;
        *root = p;
    } else {
    
    
        if((*root)->data > value){
    
    
            add(&(*root)->left,value);
        } else {
    
    
            add(&(*root)->right,value);
        }
    }
}

//先序遍历
void preorder(struct BiTree *root)
{
    
    

    if(root != NULL){
    
    
        printf("value: %d \n",root->data);
    } else {
    
    
        printf("树空\n");
    }

    if(root->left != NULL){
    
    
        preorder(root->left);
    }

    if(root->right != NULL){
    
    
        preorder(root->right);
    }

}

//初始化队列
struct BiTreeQueue initqueue()
{
    
    
    struct BiTreeQueue queue;
    queue.front = 0;
    queue.rear = 0;
    return queue;
}

//判断队列满
int IsFull(struct BiTreeQueue queue)
{
    
    
    if((queue.rear+1)%MAX == queue.front){
    
    
        return TRUE;
    }
    return FALSE;
}

//判断队空
int IsEmpty(struct BiTreeQueue queue)
{
    
    
    if(queue.front == queue.rear){
    
    
        return TRUE;
    }
    return FALSE;
}

//入队
void InQueue(struct BiTreeQueue *queue,struct BiTree *node)
{
    
    
    if(IsFull(*queue)){
    
    
        printf("队满\n");
        return;
    }
    // printf("入队元素:%d\n",node->data);
    queue->data[queue->rear] = *node;
    queue->rear = (queue->rear + 1) % MAX;
}

//出队
struct BiTree *OutQueue(struct BiTreeQueue *queue)
{
    
    
    struct BiTree *p;

    if(IsEmpty(*queue)){
    
    
        printf("队空\n");
        return NULL;
    }
    p = &(queue->data[queue->front]);
    queue->front = (queue->front + 1) % MAX;
    return p;
}

//层序遍历
/***
 * @note    
 *          按照二叉树中的层次从左到右依次遍历每层中的结点。具体的实现思路是:
 *          通过使用队列的数据结构,从树的根结点开始,依次将其左孩子和右孩子入队。
 *          而后每次队列中一个结点出队,都将其左孩子和右孩子入队,直到树中所有结点都出队(队空),出队结点的先后顺序就是层次遍历的最终结果。 
 * 
 * */
void sequence(struct BiTree *root,int *count)
{
    
    
    struct BiTreeQueue queue;
    struct BiTree *p;
    int i = 0;

    queue = initqueue();
    p = root;

    InQueue(&queue,p);

    while(!IsEmpty(queue)){
    
    

        p = OutQueue(&queue);
        if(p->left == NULL && p->right == NULL){
    
    
            (*count)++;
        }

        printf("sequence value:%d\n",p->data);

        if(p->left != NULL){
    
    
            InQueue(&queue, p->left);
        }
        if(p->right != NULL){
    
    
            InQueue(&queue,p->right);
        }

    }
}

int main()
{
    
    
    struct BiTree *root;
    int leaf_count = 0;

    init(&root);

    add(&root,11);
    add(&root,12);
    add(&root,13);
    add(&root,9);
    add(&root,2);
    add(&root,4);

    preorder(root);

    sequence(root,&leaf_count);
    printf("叶子节点数量:%d\n",leaf_count);

}

猜你喜欢

转载自blog.csdn.net/lzl980111/article/details/117780704