重温数据结构之链表二——C语言实现

链表

链表属于线性表的一种,不同于顺序表数据的内存地址是连续的,我们就在该数据结构上加一个属性,指向前后数据的内存地址,这样就将数据一串一串的连起来了,这就是链表!

链表分类

链表是有一系列的内存地址不连续的节点组成的,每个节点有两部分组成:数据域,指针域。数据域表示存储的数据,指针域指向另外一个节点,连接成串!
链表有几种:

单链表:头尾不相连,节点有下一个节点的指针(除去尾节点)
双链表:头尾不相连,节点指向上一个以及下一个节点的指针(头节点只有后继,尾节点只有前驱)
单向循环链表:头尾相连的链表,尾节点指向头节点,形成环
双向循环链表:头尾相连的链表,所有节点都有前驱以及后继,形成双向环,可以前后遍历!

简单实现

单链表实现

#include <stdio.h>
#include <malloc.h>

//单链表实现
typedef struct queue_node {

    void *data;
    struct queue_node* next;
} node;

static int count;
static node *phead = NULL;
static node* create_node(void *data) {

    node* node = malloc(sizeof(node));
    if (!node) {

        return NULL;
    }
    node->data = data;
    return node;
}

//创建链表,成功返回0,失败返回-1
int create_queue() {

    node* node = create_node(null);
    if (!node) {

        return -1;
    }
    phead = node;
    phead->next = NULL;
    count = 0;
    return 0;
}

// 链表是否为空
int queue_is_empty() {

    return count == 0;
}

// 获取链表的长度
int queue_size() {

    return count;
}

static node* get_node(int index) {

    if (index < 0 || index >= count) {

        return NULL;
    }

    int i = 0;
    node* node = phead->next;
    while (i < index) {

        node = node->next;
        i++;
    }

    return node;
}

static node* get_first_node() {

    return get_node(0);
}

static node* get_last_node() {

    return get_node(count - 1);
}

//获取index位置的元素值
void* queue_get(int index) {

    if (index < 0 || index >= count) {

        return NULL;
    }

    node* node = get_node(index);
    if (!node) {
        return NULL;
    }
    return node->data;
}

// 获取链表中第1个元素的值
void* queue_get_first() {

    node* node = get_node(0);
    if (!node) {

        return NULL;
    }
    return node->data;
}

void* queue_get_last() {

    node* node = get_node(count - 1);
    if (!node) {

        return NULL;
    }
    return node->data;
}

//向链表中插入元素,成功返回0,失败返回-1
int queue_insert(int index, void* data) {

    if (index < 0 || index > count) {

        return -1;
    }

    //新的元素
    node* newnode = create_node(data);
    if (!newnode) {

        return -1;
    }

    if (index == 0) {
        // 插入头部
        node* first_node = get_first_node();
        phead->next = newnode;
        newnode->next = first_node;
    } else if (index == count) {

        // 插入末尾
        node* lastnode = get_last_node();
        lastnode->next = newnode;
        newnode->next = NULL;
    } else {

        // 中间插入
        node* nodepre = get_node(index - 1);
        nodepre->next = newnode;
        newnode->next = nodepre->next;
    }

    count++;
    return 0;
}

int queue_insert_first(void *data) {

    return queue_insert(0, data);
}

int queue_append_last(void *pval) {

    return queue_insert(count, data);
}

int queue_delete(int index) {

    if (index < 0 || index >= count) {

        return -1;
    }

    if (index == 0) {

        // 删除首个元素
        node* nodeindex = get_node(index);
        phead->next = nodeindex->next;
        free(nodeindex);
    } else {

        node* prenode = get_node(index - 1);
        node* current = nodenode->next;
        prenode->next = current->next;
        free(current);
    }

    count--;
    return 0;
}

int queue_delete_first() {

    return queue_delete(0);
}

int queue_delete_last() {

    return queue_delete(count - 1);
}

int destroy_queue() {

    if (!phead) {

        return -1;
    }
    node* node = phead->next;
    node* q = node;
    while (node) {

        q = node;
        node = node->next;
        free(q);
    }

    free(phead);
    count = 0;
}

双链表实现

#include <stdio.h>
#include <malloc.h>

//双链表实现
typedef struct queue_node {

    void *data;
    struct queue_node* next;
    struct queue_node* pre;
} node;

static int count;
static node *phead = NULL;

// 创建node
static node* create_node(void *data) {

    node* node = malloc(sizeof(node));
    if (!node) {

        return NULL;
    }
    node->data = data;
    node->pre = node->next = NULL;
    return node;
}

// 新建“双向链表”。成功,返回0;否则,返回-1
int create_queue() {

    node* node = create_node(NULL);
    if (!node) {

        return -1;
    }

    phead = node;
    count = 0;
}

// “双向链表是否为空”。为空的话返回1;否则,返回0。
int queue_is_empty() {

    return count == 0;
}
// 返回“双向链表的大小”
int queue_size() {

    return count;
}
// 获取“双向链表中第index位置的元素”。成功,返回节点指针;否则,返回NULL。
void* queue_get(int index) {

    if (index < 0 || index >= count) {

        return NULL;
    }

    int i = 0;
    node * node = phead->next;
    while (i < index) {

        node = node->next;
        i++;
    }

    return node;
}
// 获取“双向链表中第1个元素”。成功,返回节点指针;否则,返回NULL。
void* queue_get_first() {

    return queue_get(0);
}
// 获取“双向链表中最后1个元素”。成功,返回节点指针;否则,返回NULL。
void* queue_get_last() {

    return queue_get(count - 1);
}
// 将“value”插入到index位置。成功,返回0;否则,返回-1。
int queue_insert(int index, void *value) {

    if (index < 0 || index > count) {

        return -1;
    }

    // 新建节点
    node* newnode = create_node(value);
    if (!newnode) {

        return -1;
    }

    if (index == 0) {

        // 在首个位置插入
        node* firstnode = phead->next;
        phead->next = newnode;
        newnode->pre = phead;
        newnode->next = firstnode;
        firstnode->pre = newnode;
    } else if (index == count) {

        // 在末尾插入
        node* lastnode = queue_get(index - 1);
        lastnode->next = newnode;
        newnode->pre = lastnode;
        newnode->next = NULL;

    } else {

        //在中间插入
        node* currentnode = queue_get(index);
        node* prenode = currentnode->pre;

        prenode->next = newnode;
        newnode->pre = prenode;
        newnode->next = currentnode;
        currentnode->pre = newnode;
    }
    count++;
    return 1;
}
// 将“value”插入到表头位置。成功,返回0;否则,返回-1。
int queue_insert_first(void *pval) {

    return queue_insert(0, pval);
}
// 将“value”插入到末尾位置。成功,返回0;否则,返回-1。
int queue_append_last(void *pval) {

    return queue_insert(count, pval);
}
// 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1
int queue_delete(int index) {

    if (index < 0 || index >= count) {

        return -1;
    }
    node* node = queue_get(index);
    node* prenode = node->pre;
    prenode->next = node->next;
    node->next->pre = prenode;
    free(node);
    count--;
    return 0;
}

// 删除第一个节点。成功,返回0;否则,返回-1
int queue_delete_first() {

    return queue_delete(0);
}

// 删除组后一个节点。成功,返回0;否则,返回-1
int queue_delete_last() {

    return queue_delete(count - 1);
}

// 撤销“双向链表”。成功,返回0;否则,返回-1
int destroy_queue() {

    if (!phead) {

        return -1;
    }
    node* node = phead->next;
    node * p;
    while (node) {

        p = node;
        node = node->next;
        free(p);
    }

    free(phead);
    count = 0;
}

双向循环链表实现

#include <stdio.h>
#include <malloc.h>

//双向循环链表实现
typedef struct queue_node {

    void *data;
    struct queue_node* next;
    struct queue_node* pre;
} node;

static int count;
node* phead;

// 新建“双向链表”。成功,返回0;否则,返回-1
int create_queue() {

    phead = create_node(NULL);
    if (!node) {

        return NULL;
    }
    count = 0;
    return 0;
}

node * create_node(void *data) {

    node* node = malloc(sizeof(node));
    if (!node) {

        return NULL;
    }
    node->data = data;
    node->pre = node->next = NULL;
    return node;
}

// “双向链表是否为空”。为空的话返回1;否则,返回0。
int queue_is_empty() {

    return count == 0;
}
// 返回“双向链表的大小”
int queue_size() {

    return count;
}
// 获取“双向链表中第index位置的元素”。成功,返回节点指针;否则,返回NULL。
void* queue_get(int index) {

    if (index < 0 || index >= count) {

        return NULL;
    }

    // 这里可以优化
    node* firstnode = phead->next;
    int i = 0;
    while ((i++) < index) {

        firstnode = firstnode->next;
    }

    return firstnode->data;
}
// 获取“双向链表中第1个元素”。成功,返回节点指针;否则,返回NULL。
void* queue_get_first() {

    return queue_get(0);
}
// 获取“双向链表中最后1个元素”。成功,返回节点指针;否则,返回NULL。
void* queue_get_last() {

    return queue_get(count - 1);
}
// 将“value”插入到index位置。成功,返回0;否则,返回-1。
int queue_insert(int index, void *pval) {

    if (index < 0 || index > count) {

        return -1;
    }

    node* newnode = create_node(pval);
    if (!newnode) {

        return -1;
    }
    node* nodeindex = queue_get(index);
    if (!nodeindex) {
        // index=count 在末尾插入
        node* lastnode = phead->pre;
        lastnode->next = newnode;
        newnode->pre = lastnode;
        newnode->next = phead;
        phead->pre = newnode;
    } else {
        // 不为空,在其他位置插入
        node* prenode = nodeindex->pre;
        prenode->next = newnode;
        newnode->pre = prenode;
        newnode->next = nodeindex;
        nodeindex->pre = newnode;
    }
    count++;
    return 0;
}
// 将“value”插入到表头位置。成功,返回0;否则,返回-1。
int queue_insert_first(void *pval) {

    return queue_insert(0, pval);
}
// 将“value”插入到末尾位置。成功,返回0;否则,返回-1。
int queue_append_last(void *pval) {

    return queue_insert(count, pval);
}
// 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1
int queue_delete(int index) {

    if (index < 0 || index >= count) {

        return -1;
    }

    node* indexnode = queue_get(index);
    node* prenode = indexnode->pre;
    node* nextnode = indexnode->next;
    prenode->next = nextnode;
    nextnode->pre = prenode;
    free(indexnode);
    count--;
    return 0;
}
// 删除第一个节点。成功,返回0;否则,返回-1
int queue_delete_first() {

    return queue_delete(0);
}
// 删除组后一个节点。成功,返回0;否则,返回-1
int queue_delete_last() {

    return queue_delete(count - 1);
}

// 撤销“双向链表”。成功,返回0;否则,返回-1
int destroy_queue() {

    if (!phead) {

        return -1;
    }
    node* firstnode = phead->next;
    node* p;
    while (firstnode) {

        p = firstnode;
        firstnode = firstnode->next;
        free(p);
    }
    free(phead);
    phead = NULL;
    count = 0;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值