链表
链表属于线性表的一种,不同于顺序表数据的内存地址是连续的,我们就在该数据结构上加一个属性,指向前后数据的内存地址,这样就将数据一串一串的连起来了,这就是链表!
链表分类
链表是有一系列的内存地址不连续的节点组成的,每个节点有两部分组成:数据域,指针域。数据域表示存储的数据,指针域指向另外一个节点,连接成串!
链表有几种:
单链表:头尾不相连,节点有下一个节点的指针(除去尾节点)
双链表:头尾不相连,节点指向上一个以及下一个节点的指针(头节点只有后继,尾节点只有前驱)
单向循环链表:头尾相连的链表,尾节点指向头节点,形成环
双向循环链表:头尾相连的链表,所有节点都有前驱以及后继,形成双向环,可以前后遍历!
简单实现
单链表实现
#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;
}