声明:本文参考自今日头条用户:记录我的编程生活
原文链接:合集|C语言-数据结构与算法 - 今日头条 (toutiao.com)
正文:主要是记录个人学习情况,非教程,因本人也没学明白,不想误导人,代码仅供参考!废话不多说,不讲原理,自己看书,我直接上代码(欢迎批评指正)
附上gitee仓库链接:https://gitee.com/moweida/gitee_linux.git
mylist.c:
#include <stdio.h>
#include <stdlib.h>
#include "mylist.h"
//初始化单向链表
int slist_init(single_list *list)
{
if ( NULL == list ) //判断传入的参数是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
list->head = list->tail = NULL;
printf("single_list initialized successfully\n");
return 1;
}
//初始化双向链表
int dlist_init(double_list *list)
{
if ( NULL == list ) //判断传入的参数是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
list->head = list->tail = NULL;
printf("double_list initialized successfully\n");
return 1;
}
//单向链表头插法
int slist_head_add(single_list *list, void *data)
{
single_list_node *newnode = (single_list_node*)malloc(sizeof(single_list_node));
newnode->data = data;
newnode->next = NULL;
if ( NULL == list ) //判断传入的参数是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
if ( NULL == list->head )
{
list->head = list->tail = newnode;
newnode->next = NULL;
}
else
{
newnode->next = list->head; //新节点的后继指针指向头指针指向的旧(原头结点)结点
list->head = newnode; //头指针指向新结点,成为新的头结点
}
printf("Add new node to the list head successfully\n");
return 1;
}
//单向链表尾插法
int slist_tail_add(single_list *list, void *data)
{
single_list_node *newnode = (single_list_node*)malloc(sizeof(single_list_node)); //创建一个结点并分配内存
newnode->data = data; //结点数据
newnode->next = NULL; //结点后继指针
if ( NULL == list ) //判断传入的参数是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
if ( NULL == list->tail ) //如果尾指针为空,代表链表没有任何结点
{
list-> head = list->tail = newnode; //将头指针、尾指针都指向新结点
}
else
{
list->tail->next = newnode; //否则将新结点插入链尾
list->tail = newnode; //将尾指针指向新的链尾结点
}
printf("Add new node to the list tail successfully\n");
return 1;
}
//单向链表头删法
int slist_del_head(single_list *list)
{
if ( (NULL == list) || (NULL == list->head) ) //判断传入的参数以及链表是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
single_list_node *next = list->head->next; //创建一个新结点指向头结点的后继结点
free(list->head); //释放旧的头结点
list->head = next; //后继结点成为新的头结点
printf("Delete the head node successfully\n");
return 1;
}
//单向链表尾删法
int slist_del_tail(single_list *list)
{
if ( (NULL == list) || (NULL == list->head) ) //判断传入的参数以及链表是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
single_list_node *cru = list->head; //创建一个当前结点指针,指向头结点
single_list_node *pre = cru; //创建一个前驱结点指针,指向头结点
while ( NULL != cru->next ) //遍历链表,寻找尾结点(后继指针为空的结点)
{
pre = cru; //前驱结点指针指向当前结点
cru = cru->next; //当前结点指针指向下一结点,循环移动,直到指向尾结点
}
free(cru); //释放尾结点
pre->next = NULL; //尾结点的后继指针为空
list->tail = pre; //尾指针指向新的尾结点
printf("Delete the tail node successfully\n");
return 1;
}
//双向链表头插法
int dlist_head_add(double_list *list, void *data)
{
double_list_node *newnode = (double_list_node*)malloc(sizeof(double_list_node));
newnode->data = data;
newnode->next = NULL;
if ( NULL == list ) //判断传入的参数是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
if ( NULL == list->head )
{
list->head = list->tail = newnode;
newnode->next = NULL;
}
else
{
newnode->next = list->head; //新节点的后继指针指向头指针指向的旧(原头结点)结点
list->head->prev = newnode; //头指针的前驱指针指向新结点
list->head = newnode; //头指针指向新结点,新结点成为头结点
newnode->prev = NULL; //头结点的前驱为NULL
}
printf("Add new node to the double list head successfully\n");
return 1;
}
//双向链表尾插法
int dlist_tail_add(double_list *list, void *data)
{
double_list_node *newnode = (double_list_node*)malloc(sizeof(double_list_node)); //创建一个结点并分配内存
newnode->data = data; //结点数据
newnode->next = NULL; //结点后继指针
if ( NULL == list ) //判断传入的参数是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
if ( NULL == list->tail ) //如果尾指针为空,代表链表没有任何结点
{
list-> head = list->tail = newnode; //将头指针、尾指针都指向新结点
newnode->prev = newnode->next = NULL;
}
else
{
newnode->prev = list->tail; //将新结点的前驱指针指向尾结点
list->tail->next = newnode; //否则将新结点插入链尾
list->tail = newnode; //将尾指针指向新的链尾结点
newnode->next = NULL; //尾结点的后继指针为NULL
}
printf("Add new node to the double list tail successfully\n");
return 1;
}
//双向链表头删法
int dlist_del_head(double_list *list)
{
if ( (NULL == list) || (NULL == list->head) ) //判断传入的参数以及链表是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
double_list_node *next = list->head->next; //创建一个新结点,指向头结点的后继结点
free(list->head); //释放旧的头结点
if ( NULL == next )
{
list->head = list->tail = NULL; //链表为空
}
else
{
next->prev = NULL;
list->head = next; //next成为新的头结点
}
printf("delete the head node successfully\n");
return 1;
}
//双向链表尾删法
int dlist_del_tail(double_list *list)
{
if ( (NULL == list) || (NULL == list->head) ) //判断传入的参数以及链表是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
double_list_node *prev = list->tail->prev; //创建一个当前结点指针,指向尾结点的前驱结点
free(list->tail); //释放尾结点
if ( NULL == prev ) //如果删除了尾结点后为空
{
list->head = list->tail = NULL; //链表为空
}
else
{
prev->next = NULL; //尾结点的后继为NULL
list->tail = prev; //尾指针指向前驱结点,成为新的尾结点
}
printf("delete the tail node successfully\n");
return 1;
}
//按索引查找
int slist_index_search(single_list *list, int index, void *get_data)
{
if ( (NULL == list) || (NULL == list->head) ) //判断传入的参数以及链表是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
int i = 1;
single_list_node *p = list->head; //创建一个结点指针用来遍历链表
while ( (NULL != p) && (i < index) ) //遍历链表
{
p = p->next;
i++;
}
if ( (NULL == p) || (i > index) ) //如果遍历完整个链表或者越界
{
printf("Search node of index[%d] failure\n");
return -1;
}
get_data = p->data; //找到指定序号的结点,并取出其中的数据
printf("Search node of index[%d] successfully:\n%s\n", index, get_data);
return 1;
}
//按值查找
int slist_value_search(single_list *list, void *value, void *get_data)
{
if ( (NULL == list) || (NULL == list->head) ) //判断传入的参数以及链表是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
single_list_node *p = list->head; //创建一个结点指针用来遍历链表
while ( (NULL != p) && (p->data != value) ) //遍历链表
{
p = p->next;
}
if ( (NULL == p) && (p->data != value) ) //如果遍历完整个链表都没有匹配给定数据的结点
{
printf("Search node of value(%s) failure\n", value);
return -1;
}
get_data = p->data; //找到指定数据的结点,并取出其数据
printf("Search node of value(%s) successfully\n", value);
return 1;
}
//按索引查找
int dlist_index_search(double_list *list, int index, void *get_data)
{
if ( (NULL == list) || (NULL == list->head) ) //判断传入的参数以及链表是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
int i = 1;
double_list_node *p = list->head; //创建一个结点指针用来遍历链表
while ( (NULL != p) && (i < index) ) //遍历链表
{
p = p->next;
i++;
}
if ( (NULL == p) || (i > index) ) //如果遍历完整个链表或者越界
{
printf("Search node of index[%d] failure\n");
return -1;
}
get_data = p->data; //找到指定序号的结点,并取出其中的数据
printf("Search node of index[%d] successfully:\n%s\n", index, get_data);
return 1;
}
//按值查找
int dlist_value_search(double_list *list, void *value, void *get_data)
{
if ( (NULL == list) || (NULL == list->head) ) //判断传入的参数以及链表是否为空
{
printf("Illegal pointer parameter!\n");
return -1;
}
double_list_node *p = list->head; //创建一个结点指针用来遍历链表
while ( (NULL != p) && (p->data != value) ) //遍历链表
{
p = p->next;
}
if ( (NULL == p) && (p->data != value) ) //如果遍历完整个链表都没有匹配给定数据的结点
{
printf("Search node of value(%s) failure\n", value);
return -1;
}
get_data = p->data; //找到指定数据的结点,并取出其数据
printf("Search node of value(%s) successfully\n", value);
return 1;
}
mylist.h:
#include <stdio.h>
#include <stdlib.h>
//单向链表结点结构体
typedef struct single_list_node
{
void *data; //数据域
struct single_list_node *next; //后继指针域
}single_list_node;
//双向链表结点结构体
typedef struct double_list_node
{
void *data; //数据域
struct double_list_node *prev; //后继指针域
struct double_list_node *next; //后继指针域
}double_list_node;
//单链表结构体
typedef struct single_list
{
single_list_node *head; //头指针
single_list_node *tail; //尾指针
}single_list;
//双表结构体
typedef struct double_list
{
double_list_node *head; //头指针
double_list_node *tail; //尾指针
}double_list;
//初始化链表
int slist_init(single_list *list);
int dlist_init(double_list *list);
//单向链表头插法
int slist_head_add(single_list *list, void *data);
//双向链表头插法
int dlist_head_add(double_list *list, void *data);
//单向链表尾插法
int slist_tail_add(single_list *list, void *data);
//双向链表尾插法
int dlist_tail_add(double_list *list, void *data);
//单向链表头删法
int slist_del_head(single_list *list);
//双向链表头删法
int dlist_del_head(double_list *list);
//单向链表尾删法
int slist_del_tail(single_list *list);
//双向链表尾删法
int dlist_del_tail(double_list *list);
//按序号查找
int slist_index_search(single_list *list, int index, void *get_data);
//按值查找
int slist_value_search(single_list *list, void *value, void *get_data);
//按序号查找
int dlist_index_search(double_list *list, int index, void *get_data);
//按值查找
int dlist_value_search(double_list *list, void *value, void *get_data);
main.c(个人测试用)
#include <stdio.h>
#include <stdlib.h>
#include "mylist.h"
int main(int argc, char **argv)
{
single_list *list1 = (single_list*)malloc(sizeof(single_list));
double_list *list2 = (double_list*)malloc(sizeof(double_list));
void *get_data11;
void *get_data12;
void *get_data21;
void *get_data22;
slist_init(list1); //初始化单向链表
slist_head_add(list1, "single head"); //单向链表头插法
slist_tail_add(list1, "single tail"); //单向链表尾插法
slist_index_search(list1, 1, get_data11); //单向链表按索引查找
slist_value_search(list1, "single head", get_data12); //单向链表按值查找
slist_del_head(list1); //单向链表删除头结点
slist_del_tail(list1); //单向链表删除尾结点
dlist_init(list2); //初始化双向链表
dlist_head_add(list2, "double head"); //双向链表头插法
dlist_tail_add(list2, "double tail"); //双向链表尾插法
dlist_index_search(list2, 1, get_data21); //双向链表按索引查找
dlist_value_search(list2, "double head", get_data22); //双向链表按值查找
dlist_del_head(list2); //双向链表删除头结点
dlist_del_tail(list2); //双向链表删除尾结点
return 1;
}