/*************************************************************************
> File Name: ctr_list.c
> Author: khalil
> Mail: hsgwpj@gmail.com
> Created Time: Sat 21 Nov 2015 09:11:34 AM CST
************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
// 《C语言接口与实现》 *
// C的面向对象: lua
// redis 键值对数据库
//比较优秀的网站:
// stackoverflow
// sourceforge
#if 1
//为bool类型宏定义
#define true (1)
#define false (0)
#define ZERO (0)
#define ONLY_ONE (1)
#define TWO (2)
#define get_data_size() ((unsigned long)&(((List_node *)0)->next))
//链表控制信息:
//
// 1.头、尾节点位置
// 2.链表元素数量
//
//链表节点信息:
//
// 1.数据域
// 2.指针域
//节点:
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;
typedef unsigned char bool;
static void *Malloc(size_t size); //包裹函数
static List_node *create_node(void);//创建节点
static void swap(void *a, void *b, int len);//交换data
static void reverse_show_list_node(List_node *p);//组件
static void swap(void *a, void *b, int len)
{
void *tmp = Malloc(len);
memcpy(tmp, a, len);
memcpy(a, b, len);
memcpy(b, tmp, len);
free(tmp);
}
static List_node *create_node(void)
{
List_node *node = (List_node *)Malloc(sizeof(List_node));
bzero(node, sizeof(List_node));
return node;
}
static void *Malloc(size_t size)
{
void *result = malloc(size);
if(result == NULL){
fprintf(stderr, "Memory Full!\n");
exit(1);
}
return result;
}
static void reverse_show_list_node(List_node *p)
{
if(p){
reverse_show_list_node(p->next);
printf("%d\t", p->data);
}
}
//链表接口:
List *init_list(void); //链表的初始化
void destory_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 *merge_two_lists_recure(List *list1, List *list2); //合并两个有序链表(递归)
List_node *find_revise_node(List *list, int num); //找到链表的倒数第num个节点
List_node *find_mid_node (List *list); //找到链表的中间节点
List *reverse_list (List *list); //逆置一个链表
List *list_dump (List *list); //链表拷贝
void reverse_show_list(List *list); //逆序输出一个链表
bool is_lists_intersect (List *list1, List *list2); //判断链表是否相交
List_node *get_first_common_node(List *list1, List *list2); //得到第一个交点
void delete_one_node (List *List, List_node *node);//在O(1)的时间复杂度下删除节点
bool has_circle (List *list, List_node **intersect); //判断一个链表是否有环
List_node *find_circle_first_node(List *list); //找到带环链表的环入口点
// 接口实现 //
List *init_list(void) //链表的初始化
{
List *list = (List *)Malloc(sizeof(List));
// head && tail && count --> NULL/0
bzero(list, sizeof(List));
return list;
}
void destory_list(List **list) //链表的销毁
{
if(list == NULL || *list == NULL){
return;
}
//遍历释放空间
//List *p_list = *list;
//List_node *p_node = p_list->head;
//List_node *q_node = NULL;
//删除链表节点信息
//while(p_node){
// q_node = p_node;
// p_node = p_node->next;
// free(q_node);
//}
//删除链表节点信息
while((*list)->count){
pop_front(*list);
}
//删除链表控制信息
free(*list);
*list = NULL;
}
bool push_front(List *list, int value) //头部插入
{
if(list == NULL){
return false;
}
//创建节点并赋值
List_node *node = create_node();
node->data = value;
if(list->count == ZERO){
// case 1:空链表
// head && tail -> node_1; count = 1
list->head = list->tail = node;
}else{
// case 2:非空链表
// head -> node_1 ; tail -> node_n; count = n + 1
node->next = list->head;
list->head = node;
}
list->count++;
return true;
}
bool push_back (List *list, int value) //尾部插入
{
if(list == NULL){
return false;
}
List_node *node = create_node();
node->data = value;
if(list->count == ZERO){
//case 1: 空链表
list->head = list->tail = node;
}else{
//case 2: 非空链表
list->tail->next = node;
list->tail = node;
}
list->count++;
return true;
}
bool pop_front (List *list) //头部删除
{
if(list == NULL || list->count == ZERO){
return false;
}
List_node *p_node = list->head;
//case 1:只有一个节点
//case 2:大于一个节点
if(list->count == ONLY_ONE){
list->head = list->tail = NULL;
}else{
list->head = list->head->next;
}
free(p_node);
list->count--;
return true;
}
bool pop_back (List *list) //尾部删除
{
if(list == NULL || list->count == ZERO){
return false;
}
List_node *p_node = list->head;
//case 1:只有一个节点
//case 2:大于一个节点
if(list->count == ONLY_ONE){
list->head = list->tail = NULL;
free(p_node);
}else{
//遍历一遍链表 将p_node指向倒数第二个节点
while(p_node->next != list->tail){
p_node = p_node->next;
}
free(list->tail);
list->tail = p_node;
p_node->next = NULL;
}
list->count--;
return true;
}
void show_list (List *list) //显示链表信息
{
if(list != NULL && list->count != ZERO){
List_node *p_node = list->head;
for( ; p_node; p_node = p_node->next ){
printf("%d\t",p_node->data);
}
printf("\n");
}
}
void sort_list_ascend (List *list) //升序排列
{
if(list == NULL || list->count < TWO){
return ;
}
List_node *p_node = NULL;
List_node *q_node = NULL;
unsigned long data_size = 0;
data_size = get_data_size();//求数据区域大小
for(p_node = list->head; p_node->next; p_node = p_node->next){
for(q_node = p_node->next; q_node; q_node = q_node->next){
if(p_node->data > q_node->data){
swap(p_node, q_node, data_size);
}
}
}
}
void sort_list_descend(List *list) //降序排列
{
if(list == NULL || list->count < TWO){
return ;
}
List_node *p_node = NULL;
List_node *q_node = NULL;
unsigned long data_size = 0;
data_size = get_data_size();//求数据区域大小
for(p_node = list->head; p_node->next; p_node = p_node->next){
for(q_node = p_node->next; q_node; q_node = q_node->next){
if(p_node->data < q_node->data){
swap(p_node, q_node, data_size);
}
}
}
}
int get_list_count (List *list) //得到链表节点数量
{
if(list == NULL){
return -1;
}
return list->count;
}
List *merge_two_lists (List *list1, List *list2) //合并两个有序链表
{
List *result = NULL;
if(list1 == NULL || list2 == NULL){
return result;
}
result = init_list();
List_node *p = list1->head;
List_node *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;
}
}
//如果有一个比较完了,把另一个直接进行拷贝
if(p == NULL){
while(q){
push_back(result, q->data);
q = q->next;
}
}
if(q == NULL){
while(p){
push_back(result, p->data);
p = p->next;
}
}
return result;
}
List *merge_two_lists_recure(List *list1, List *list2) //合并两个有序链表(递归)
{
//使用组件来进行递归输出!
}
List_node *find_revise_node(List *list, int num) //找到链表的倒数第num个节点
{
if(list == NULL || num <= 0 && num > list->count){
return NULL;
}
List_node *p = list->head;
int time = list->count - num;
while(time--){
p = p->next;
}
return p;
}
List_node *find_mid_node (List *list) //找到链表的中间节点
{
// 1.快慢指针:
// 一个一次走两步 一个一次走一步
//
// 2.count/2找指针
if(list == NULL){
return NULL;
}
#if 1
List_node *p = list->head;
List_node *q = p;
while(p){
p = p->next;
if(p){
p = p->next;
}
q = q->next;
}
return q;
#endif
#if 0
List_node *p = list->head;
int time = list->count >> 1;
while(time--){
p = p->next;
}
return p;
#endif
}
List *reverse_list (List *list) //逆置一个链表
{
if(list == NULL || list->count < TWO){
return list;
}
#if 0
//创建一个新的链表 与数组
int datas[list->count];
List_node *p = list->head;
List *result = init_list();
int i = 0;
for( ; i < list->count; ++i ){
datas[i] = p->data;
p = p->next;
}
for( ; i; --i ){
push_back(result, datas[i-1]);
}
return result;
#endif
#if 1
//不创建新链表 使用三个指针进行赋值
if(list->count == TWO){
//如果只有两个节点
list->tail->next = list->head;
list->head->next = NULL;
return list;
}
List_node *p = list->head;
List_node *q = p->next;
List_node *r = q->next;
p->next = NULL;
do{
q->next = p;
p = q;
q = r;
r = r->next;
}while(r);
q->next = p;
swap(&(list->head), &(list->tail), sizeof(List_node *));
return list;
#endif
}
List *list_dump (List *list) //链表拷贝
{
if(list == NULL){
return NULL;
}
List *result = init_list();
List_node *p = list->head;
while(p){
push_back(result, p->data);
p = p->next;
}
return result;
}
void reverse_show_list(List *list) //逆序输出一个链表
{
if(list == NULL){
return;
}
//递归逆序输出比较好
reverse_show_list_node(list->head);
//使用组件来输出
}
bool is_lists_intersect (List *list1, List *list2) //判断链表是否相交
{
if (list1 == NULL || list2 == NULL){
return false;
}
return (list1->tail == list2->tail);
}
List_node *get_first_common_node(List *list1, List *list2) //得到第一个交点
{
if(! is_lists_intersect(list1, list2)){
return NULL;
}
int list1_len = list1->count;
int list2_len = list2->count;
int distance = 0;
List_node *p = list1->head;
List_node *q = list2->head;
//将始末差距移动到相同距离
if(list1_len > list2_len){
distance = list1_len - list2_len;
while(distance--){
p = p->next;
}
}else{
distance = list2_len - list1_len;
while(distance--){
q = q->next;
}
}
//依次对对应节点进行判断是否相等,相等则为第一个相交界点
while(p != q){
p = p->next;
q = q->next;
}
return p;
}
void delete_one_node (List *list, List_node *node)//在O(1)的时间复杂度下删除节点
{
if(list == NULL || node == NULL){
return ;
}
List_node *p = NULL;
if(node != list->tail){
//不是末尾
p = node->next;
node->data = p->data;
node->next = p->next;
free(p);
list->count--;
}else{
//是末尾
pop_back(list);
}
}
bool has_circle (List *list, List_node **intersect) //判断一个链表是否有环
{
if(list ==NULL || list->count < TWO){
return false;
}
//快慢指针跑环
//如果有环的话两者一定会相遇
List_node *fast = list->head;
List_node *slow = fast;
do{
fast = fast->next;
fast = fast->next;
slow = slow->next;
if(fast == slow){
if(intersect){
//将相交节点赋值给intersect
*intersect = fast;
}
return true;
}
}while(fast && fast->next);
return false;
}
List_node *find_circle_first_node(List *list) //找到带环链表的环入口点
{
List_node *intersect = NULL;
if(! has_circle(list, &intersect)){
return NULL;
}
//转化为求两个相交链表的第一个结点的问题
List_node *list1_head = list->head;
List_node *list2_head = intersect->next;
//求得二个链表的长度
List_node *p = list1_head;
List_node *q = list2_head;
int list1_len = 0;
int list2_len = 0;
int distance = 0;
while(p != intersect){
list1_len++;
p = p->next;
}
while(q != intersect){
list2_len++;
q = q->next;
}
p = list1_head;
q = list2_head;
//移动较长的链表 移动距离为两个长度的差
if(list1_len > list2_len){
distance = list1_len - list2_len;
while(distance--){
p = p->next;
}
}else{
distance = list2_len - list1_len;
while(distance--){
q = q->next;
}
}
while(p != q){
p = p->next;
q = q->next;
}
return q;
}
/// 测试 //
int main(int argc, char **argv)
{
List* list = init_list(); //initialize
List* list1 = init_list();
List* tmp = NULL;
int i = 0;
for (i = 0; i < 10; ++i){
push_back(list, rand() % 200);
push_back(list1, rand() % 233);
}
printf("list:\n");
sort_list_ascend(list);
show_list(list);
printf("list1:\n");
sort_list_ascend(list1);
show_list(list1);
printf("\nmerge_result:\n");
List* result = merge_two_lists(list, list1);
show_list(result);
List_node *p = find_revise_node(list, 1);
printf("\nrevise_1_p:%d\n", p->data);
List_node *mid = find_mid_node(list);
printf("mid:%d\n", mid->data);
reverse_list(list1);
printf("reve:\n");
show_list(list1);
tmp = list_dump(list1);
printf("copy:\n");
show_list(tmp);
printf("reve_show:\n");
reverse_show_list(tmp);
destory_list(&tmp);
destory_list(&list);
destory_list(&list1);
destory_list(&result);
return 0;
}
#endif
【2015/11/21】 数据结构学习日志_Day17 双端链表
最新推荐文章于 2024-04-30 20:54:45 发布