C语言-双向链表

双向链表,主要是构建了一个向前地址的指针p_prev,用于指向前面的指针地址

02link.h

/*
构造链表的结构体
*/
#ifndef __02LINK_H__ 
#define __02LINK_H__ 

#include <stdio.h>
#include <stdlib.h>
typedef struct node{
    int val; 
    struct node *p_next; 
    struct node *p_prev; 
} node; 

typedef struct {
    node head; 
    node tail; 
    node *p_cur; 
} link; 

void link_init(link *);

void link_deinit(link *);

int link_size(link *);

//判断链表是否为空 
int link_empty(link *);
//在链表最后插入数字 
int link_append(link *, int);

//在头部插入数据 
int link_head(link *, int );

//从小到大的插入顺序 
int link_insert(link *, int );
//删除最后一个数字 
int link_remove_tail(link *);

//从链表中删除最前面的数字 
int link_remove_head(link *);

//删除链表中间的某个数 
int link_remove(link *, int );
int link_get_tail(link *, int *);

//获得最前面的数字
int link_get_head(link *, int *);

//根据索引获取其中的一个数 
int link_get(link *, int *, int );

void link_begin(link *);

int link_next(link *, int *);

#endif 

02link.c

/*
构造链表的结构体
*/
#include <stdio.h>
#include <stdlib.h>
#include "02link.h"

void link_init(link *p_link) {
    //将头指针指向尾指针 
    p_link->head.p_next = &p_link->tail; 
    p_link->tail.p_prev = &p_link->head; 
    //将尾指针对应的指针地址设置为0 
    p_link->tail.p_next = NULL; 
    p_link->head.p_prev = NULL; 
    p_link->p_cur = NULL; 
}

void link_deinit(link *p_link) {
    while (p_link->head.p_next != &p_link->tail) {
        node *p_first = &p_link->head; 
        node *p_mid = p_first->p_next; 
        node *p_last = p_mid->p_next; 
        p_first->p_next = p_last; 
        p_last->p_prev = p_first; 
        free(p_mid); 
        p_mid = NULL; 
    }
}

int link_size(link *p_link) {
    node* p_tmp = NULL; 
    int cnt = 0; 
    for (p_tmp = &p_link->head;p_tmp != &p_link->tail;p_tmp = p_tmp->p_next) {
        node *p_first = p_tmp; 
        node *p_mid = p_first->p_next; 
        node *p_last = p_mid->p_next; 
        if (p_mid != &p_link->tail) {
            cnt++; 
        }
    }
    return cnt; 
}

//判断链表是否为空 
int link_empty(link *p_link) {
    return (!link_size(p_link)); 
}

//在链表最后插入数字 
int link_append(link *p_link, int val) {
    node *p_node = NULL; 
    node *p_tmp = NULL; 
    p_node = (node*)malloc(sizeof(node));
    if (!p_node) {
         free(p_node); 
        p_node = NULL; 
        return 0; 
    }
    p_node->val = val; 
    node* p_last = &p_link->tail; 
    node* p_mid = p_last->p_prev; 
    p_last->p_prev = p_node; 
    p_node->p_prev = p_mid; 
    return 1; 
}

//在头部插入数据 
int link_head(link *p_link, int val) {
    node *p_node = NULL; 
    node *p_tmp = NULL; 
    p_node = (node*)malloc(sizeof(node)); 
    if (!p_node) {
        free(p_node); 
        p_node = NULL; 
        return 0; 
    }
    p_node->val = val; 
    node* p_first = &p_link->head; 
    node* p_mid = p_first->p_next; 
    p_first->p_next = p_node; 
    p_node->p_next = p_mid; 
    return 1;     
}

//从小到大的插入顺序 
int link_insert(link *p_link, int val) {
    node *p_node = NULL; 
    node *p_tmp = NULL;
    p_node = (node*)malloc(sizeof(node));  
    if(!p_node) {
        free(p_node); 
        p_node = NULL; 
        return 0; 
    }
    p_node->val = val; 
    for (p_tmp = &p_link->head;p_tmp != &p_link->tail;p_tmp = p_tmp->p_next) {
        node *p_first = p_tmp; 
        node *p_mid = p_first->p_next; 
        node *p_last = p_mid->p_next; 
        if (p_mid->val > val || p_mid == &p_link->tail) {
            p_first->p_next = p_node; 
            p_node->p_next = p_mid; 
            return 1; 
        }
    }

}

//删除最后一个数字 
int link_remove_tail(link *p_link) {
    node *p_node = NULL; 
    node *p_tmp = NULL; 
    p_node = (node*)malloc(sizeof(node)); 
    if (!p_node) {
        free(p_node); 
        p_node = NULL; 
        return 0; 
    }
    node* p_last = &p_link->tail;
    node* p_mid = p_last->p_prev; 
    node* p_first = p_mid->p_prev; 
    p_last->p_prev = p_first; 
    free(p_mid); 
    p_mid = NULL; 
    return 1; 
}

//从链表中删除最前面的数字 
int link_remove_head(link *p_link) {
    node *p_node = NULL; 
    node *p_tmp = NULL; 
    p_node = (node* )malloc(sizeof(node)); 
    if (!p_node) {
        free(p_node); 
        p_node = NULL; 
        return 0; 
    }
    node* p_first = &p_link->head; 
    node* p_mid = p_first->p_next; 
    node* p_last = p_mid->p_next; 
    p_first->p_next = p_last; 
    free(p_mid); 
    p_mid = NULL; 
    return 1; 
}

//删除链表中间的某个数 
int link_remove(link *p_link, int val) {
    node *p_tmp = NULL;
     node *p_node = NULL; 
    p_node = (node*)malloc(sizeof(node)); 
    if (!p_node){
        free(p_node); 
        p_node = NULL; 
        return 0; 
    }
    for (p_tmp = &p_link->head;p_tmp != &p_link->tail;p_tmp = p_tmp->p_next) {
        node* p_first = p_tmp; 
        node* p_mid = p_first->p_next; 
        node* p_last = p_mid->p_next; 
        if (p_mid->val == val) {
            p_first->p_next = p_last; 
            free(p_mid); 
            p_mid = NULL;
            return 1;  
        }
    }
    return -1; 
}

//获得末尾的数字 
int link_get_tail(link *p_link, int *p_val) {
    node *p_node = NULL; 
    node *p_tmp = NULL; 
    if (p_link->head.p_next == &p_link->tail) {
        return 0; 
    }
    node* p_last = &p_link->tail; 
    node* p_mid = p_last->p_prev; 
    *p_val = p_mid->val; 
    return 1; 
}

//获得最前面的数字
int link_get_head(link *p_link, int *p_val) {
    node *p_node = NULL;
     node *p_tmp = NULL; 
    if (p_link->head.p_next == &p_link->tail) {
        return 0; 
    }
    node* p_first = &p_link->head; 
    node* p_mid = p_first->p_next; 
    *p_val = p_mid->val; 
    return 1;  
}

//根据索引获取其中的一个数 
int link_get(link *p_link, int *p_val, int sn){
    int cnn = 0; 
    node* p_tmp = NULL; 
    if (p_link->head.p_next == &p_link->tail) {
        return 0; 
    }
    for (p_tmp = &p_link->head;p_tmp != &p_link->tail;p_tmp = p_tmp->p_next) {
        node* p_first = p_tmp; 
        node* p_mid = p_first->p_next; 
        node* p_last = p_mid->p_next; 
        if (sn == cnn && p_mid != &p_link->tail) {
            *p_val = p_mid->val; 
        
        }
        cnn++; 
    }
    return 1; 

}

//获得开始的位置 
void link_begin(link *p_link) {
    p_link->p_cur = &p_link->head; 
}

//获得将当前位置移动到下一个位置 
int link_next(link *p_link, int *p_val) {
    if (!p_link->p_cur) {
        return 0; 
    }
    p_link->p_cur = p_link->p_cur->p_next;
    if (p_link->p_cur == &p_link->tail) {
        p_link->p_cur = NULL; 
        return 0; 
    } 
    else {
        *p_val = p_link->p_cur->val;
        return 1; 
    }
}

02main.c

/*
链表调用 
*/
#include <stdio.h>
#include "02link.h"
int main() {
    link l = {0}; 
    link_init(&l); 
    int val = 0; 
    printf("链表是否为空%d\n", link_empty(&l)); 
    printf("链表的size是%d\n", link_size(&l)); 
    link_append(&l, 12); 
    link_head(&l, 10); 
    link_insert(&l, 11); 
    link_insert(&l, 14); 
    printf("链表是否为空%d\n", link_empty(&l)); 
    printf("链表的size是%d\n", link_size(&l));
    
    //link_remove(&l, 12);
    /*
    link_get(&l, &val, 0); 
    printf("val的数据是%d\n", val); 
    link_get(&l, &val, 1); 
    printf("val的数据是%d\n", val); 
    link_get(&l, &val, 2); 
    printf("val的数据是%d\n", val); 
    */ 
    link_begin(&l); //获得开始目录    
    for(int i = 0;i < link_size(&l);i++) {
        link_next(&l, &val); 
        printf("%d ", val); 
    }
    printf("\n"); 

    link_deinit(&l); 


}

 

posted @ 2020-03-29 16:36  c语言我的最爱  阅读(245)  评论(0编辑  收藏  举报