list.h
#ifndef _LIST_H_
#define _LIST_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE (1)
#define FALSE (0)
#define ZERO (0)
typedef unsigned char Bool;
typedef struct List_Node{
int data; //数据域
struct List_Node *next; //指针域
}List_Node; //结点结构体
typedef struct List{
struct List_Node *head; //头指针
struct List_Node *tail; //尾指针
int count; //节点数目
}List; //带有控制信息的链表结构体
List *init_list(void); //创建链表
void destroy_list(List **list); //销毁链表
Bool push_front(List *list, int value); //链表头插
Bool push_back(List *list, int value); //链表尾插
Bool pop_front(List *list); //头部删除
Bool pop_back(List *list); //尾部删除
void show_list(List *list); //显示链表
void sort_list_ascend(List *list); //升序排序
void sort_list_descend(List *list); //降序排序
int get_list_count(List *list); //统计节点数目
List *merge_two_lists(List *list1, List *list2); //合并两个有序链表
List_Node *find_revise_node(List *list, int num);
//找到倒数第N个结点
List_Node *find_middle_node(List *list); //找到中间结点
List *reverse_list(List *list); //链表逆置
List *copy_list(List *list);//链表拷贝
Bool is_list_intersect(List *list1, List *list2);
//判断链表是否有交点
List_Node *find_first_common_node(List *list1, List *list2); //找到链表第一个交点
void delete_list_node(List *list, List_Node *node);//删除链表结点
Bool has_circle1(List *list); //判断是否有环
Bool has_circle2(List *list,List_Node **intersect); //判断是否有环
List_Node *find_circle_begin1(List *list); //找到环的入口
List_Node *find_circle_begin2(List *list); //找到环的入口
#endif
list.c
#include "list.h"
#define data_size(Node) (((char *)(Node + 1) - sizeof(void *)) -((char *)(Node)))
List_Node *create_node(void);
void Swap(void *a, void *b, int length);
List *init_list(void)
{
//申请链表空间,用0填充
List *list = NULL;
list = (List *)malloc(sizeof(List));
memset(list, 0, sizeof(List));
return list;
}
List_Node *create_node(void)
{
//申请结点空间
List_Node *node = (List_Node *)malloc(sizeof(List_Node));
memset(node, 0, sizeof(List_Node));
return node;
}
Bool push_front(List *list, int value) //链表头插
{
List_Node *node = NULL;
if(list == NULL)
{
return FALSE;
}
node = create_node(); //插入结点,需要申请结点空间
node->data = value;
//
//如果链表节点数为0,则尾指针和头指针都指向新插入的节点
//若不为0,则需要用头指针实现插入操作
if(list->count)
{
node->next = list->head;
list->head = node;
}
else{
list->head = list->tail = node;
}
list->count++;
return TRUE;
}
Bool push_back(List *list, int value) //链表尾插
{
List_Node *node = NULL;
if(list == NULL)
{
return FALSE;
}
//由于尾指针指向的是需要删除的节点,所以需要用
//头指针找到尾指针的前一个节点
node = create_node();
node->data = value;
if(list->count)
{
list->tail->next = node;
list->tail = node;
}
else{
list->head = list->tail = node;
}
list->count++;
return TRUE;
}
Bool pop_front(List *list)
{
List_Node *Node = NULL;
if(list == NULL || list->count == ZERO)
{
return FALSE;
}
//如果节点为1,则直接置空头尾指针,并释放节点空间
//如果节点不为1,则需要用头指针进行删除操作
Node = list->head;
if(list->count == 1)
{
list->head = list->tail = NULL;
}
else{
list->head = list->head->next;
}
free(Node);
list->count--;
return TRUE;
}
Bool pop_back(List *list)
{
List_Node *Node = NULL;
if(list == NULL || list->count == ZERO)
{
return FALSE;
}
Node = list->head;
if(list->count == 1)
{
list->head = list->tail = NULL;
free(Node);
}
else{
while(Node->next != list->tail)
{
Node = Node->next;
}
free(list->tail);
list->tail = Node;
Node->next = NULL;
}
list->count--;
return TRUE;
}
void destroy_list(List **list)
{
//如果链表指针不存在,或者指向的空间不存在
//则证明链表不存在,不需要进行销毁
if(list == NULL || *list == NULL)
{
return;
}
//销毁链表,需要将节点清空,并释放空间
while((*list)->count)
{
pop_front(*list);
}
free(*list);
*list == NULL;
}
void show_list(List *list)
{
List_Node *Node = NULL;
if(list != NULL && list->count > 0)
{
for(Node = list->head; Node; Node = Node->next)
{
printf("%d ", Node->data);
}
printf("\n");
}
}
void Swap(void *a, void *b, int length)
{ //内存拷贝函数交换节点数据域
void *temp = malloc(length);
memcpy(temp, a, length);
memcpy(a, b, length);
memcpy(b, temp, length);
free(temp);
}
void sort_list_ascend(List *list)
{
List_Node *p = NULL;
List_Node *q = NULL;
//链表为空,或节点少于2时不需要排序
if(list == NULL || list->count < 2)
{
return;
}
//冒泡排序节点进行排序
for(p = list->head; p->next; p = p->next)
for(q = p->next; q->next; q = q->next)
if(p->data > q->data)
{
Swap(p, q, data_size(p));
}
}
void sort_list_descend(List *list);//参考上面
int get_list_count(List *list)
{
//链表为空,返回-1
if(list == NULL)
return -1;
return list->count;
}
List *copy_list(List *list)
{
List *result = NULL;
List_Node *Node = NULL;
if(list == NULL)
{
return result;
}
Node = list->head;
result = init_list();
//尾插法实现链表拷贝
while(Node)
{
push_back(result, Node->data);
Node = Node->next;
}
return result;
}
List *merge_two_lists(List *list1, List *list2)
{
List *result = NULL;
List_Node *p = NULL;
List_Node *q = NULL;
//若某一个链表为空,则拷贝另一个链表
if(list1 == NULL)
{
return copy_list(list2);
}else if(list2 == NULL){
return copy_list(list1);
}
result = init_list();
p = list1->head;
q = list2->head;
//比较两个链表,进行合并
while(p && q)
{
if(p->data <= q->data)
{
push_back(result, p->data);
p = p->next;
}else{
push_back(result, q->data);
q = q->next;
}
}
//将未拷贝完的链表插入结果链表
while(p)
{
push_back(result, p->data);
p = p->next;
}
while(q)
{
push_back(result, q->data);
q = q->next;
}
return result;
}
List_Node *find_revise_node(List *list, int num) //找到倒数第N个节点
{
List_Node *Node = NULL;
int move = 0;
if(list == NULL || num <= 0 || num > list->count)
{
return NULL;
}
Node = list->head;
move = list->count - num;
while(move--)
{
Node = Node->next;
}
return Node;
}
List_Node *find_middle_node(List *list)
{
List_Node *Node = NULL;
int move = 0;
if(list = NULL)
{
return NULL;
}
Node = list->head;
move = list->count >> 1; //移位除以2
while(move--)
{
Node = Node->next;
}
return Node;
}
List *reverse_list(List *list) //逆置链表
{
List_Node *p_node = NULL;
List_Node *q_node = NULL;
List_Node *m_node = NULL;
if(list == NULL || list->count < 2)
{
return list;
}
if(list->count == 2)
{
list->tail->next = list->head;
list->head->next = NULL;
}
//
//循环将节点的next指向上一个节点
//最后交换head和tail
//
else{
p_node = list->head;
q_node = p_node->next;
m_node = q_node->next;
p_node->next = NULL;
do{
q_node->next = p_node;
p_node = q_node;
q_node = m_node;
m_node = m_node->next;
}while(m_node);
q_node->next = p_node;
}
Swap(&list->head, &list->tail, sizeof(List_Node *));
return list;
}
Bool is_list_intersect(List *list1, List *list2) //判断是否有交点
{
if(list1 == NULL || list2 == NULL)
{
return FALSE;
}
return list1->tail == list2->tail;
}
List_Node *find_first_common_node(List *list1, List *list2)//如果有交点,找到第一个交点
{
int len_list1 = 0;
int len_list2 = 0;
int move = 0;
List_Node *p_node = NULL;
List_Node *q_node = NULL;
if(!is_list_intersect(list1,list2))
{
return NULL;
}
len_list1 = list1->count;
len_list2 = list2->count;
p_node = list1->head;
q_node = list2->head;
if(len_list1 >= len_list2)
{
move = len_list1 - len_list2;
while(move--)
{
p_node = p_node->next;
}
}
else{
move = len_list2 - len_list1;
while(move)
{
q_node = q_node->next;
}
}
while(p_node != q_node)
{
p_node = p_node->next;
q_node = q_node->next;
}
return p_node;
}
void delete_list_node(List *list, List_Node *Node)
{
List_Node *p_node = NULL;
if(list == NULL || Node == NULL)
{
return;
}
if(Node != list->tail)
{
p_node = Node->next;
Node->data = p_node->data;
Node->next = p_node->next;
free(p_node);
list->count--;
}else{
pop_back(list);
}
}
Bool has_circle1(List *list) //
{
List_Node *Node = NULL;
if(list == NULL || list->count < 2 ||
list->tail->next == NULL)
{
return FALSE;
}
Node = list->head;
while(Node != NULL)
{
if(list->tail->next = Node)
{
return TRUE;
}
Node = Node->next;
}
return FALSE;
}
Bool has_circle2(List *list, List_Node **intersect)
{
List_Node *fast = NULL;
List_Node *slow = NULL;
if(list == NULL || list->count < 2 || list->tail->next == NULL)
return FALSE;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
if(intersect != NULL)
{
*intersect == fast;
}
return TRUE;
}
}
return FALSE;
}
List_Node *find_circle_begin1(List *list)
{
if(!has_circle1(list))
{
return NULL;
}
return list->tail->next;
}
List_Node *find_circle_begin2(List *list)
{
List_Node *intersect = NULL;
if(!has_circle2(list, &intersect))
{
return NULL;
}
return intersect;
}
main.c
#include "list.h"
int main(int argc, char const* argv[])
{
List *list1 = init_list();
List *list2 = init_list();
List *list3 = NULL;
for(int i = 0; i < 5; i++)
{
push_back(list1, i);
}
printf("list1:\n");
show_list(list1);
for(int i = 0; i < 10; i= i+2)
{
push_back(list2, i);
}
printf("list2:\n");
show_list(list2);
sort_list_ascend(list1);
sort_list_ascend(list2);
list3 = merge_two_lists(list1, list2);
show_list(list3);
reverse_list(list3);
show_list(list3);
destroy_list(&list1);
destroy_list(&list2);
destroy_list(&list3);
return 0;
}