【2015/11/21】 数据结构学习日志_Day17 双端链表
2015-11-26 00:42
375 查看
/************************************************************************* > 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
相关文章推荐
- leetcode之Rotate Array
- redis数据结构-链表
- 双向链表
- 数据结构与算法(4)--队列
- 机器学习模型数据结构:logistic regression, neural network, convolutional neural network
- 数据结构学习(C++)—二叉树
- 深度优先搜索——毕业BG
- 黑马程序员—Java基础—java基础语法:数据结构,运算符,选择结构,循环结构
- 数据结构基础6.3:最小生成树MST(Prim、Kruskal)
- 用c语言实现二分法查找表格【数据结构】
- 数据结构——建立单向链表(java实现)
- MySQL索引背后的数据结构及算法原理
- 二叉树
- 数据结构基础6.2:图的遍历
- 数据结构之 --- 树的应用(并查集)
- 几种查找数组的前K个最小值的算法
- 数据结构
- javascript数据结构之双链表插入排序实例详解
- SQL笔记(2)_第二章 定义数据结构
- 学习数据结构与算法分析如何帮助您成为更优秀的开发人员