数据结构之单链表的实现
2016-03-29 23:58
429 查看
单链表:
特点: 链表的链接方向是单向的;
链表是由节点构成,每个节点由两部分(节点数据和指向下一节点的指针);
>
链表的结构体及变量重定义如下:
>
链表的常用接口如下:
链表的接口实现
链表的测试代码如下:
测试结果如下:
特点: 链表的链接方向是单向的;
链表是由节点构成,每个节点由两部分(节点数据和指向下一节点的指针);
>
链表的结构体及变量重定义如下:
#ifndef LIST_H_ #define LIST_H_ #define ONE 1 #define ZERO 0 #define TWO 2 //const int TRUE = 1; //const int FALSE = 0; enum BOOL { FALSE, TRUE }; typedef unsigned char Boolean; //定义连表的控制节点 typedef struct List{ struct List_node *head; struct List_node *tail; int count; }List; typedef struct List_node{ int data; struct List_node *next; }List_node;
>
链表的常用接口如下:
List *init_list(void) ; //链表的初始化 void destroy_list(List **list) ; //连表的销毁 Boolean push_front(List *list, int value) ; //头部插入 Boolean push_back(List *list, int value) ; //尾部插入 Boolean pop_front(List *list) ; //头部删除 Boolean pop_back(List *list) ; //尾部删除 void print_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) ; //找到连表倒数第num个节点 List_node *find_middle_node(List *list) ; //得到链表的中间节点 List *reverse_list(List *list) ; //逆置链表 List *copy_list(List *list) ; //链表的拷贝 Boolean is_list_intersect(List *list1, List *list2) ; //判断两个链表是否有交点 List_node *find_first_common_node(List *list1, List *list2); //找到两个链表的第一个交点 void delete_one_node(List *list, List_node *node) ; //删除链表的一个节点 Boolean has_circle(List *list) ; //判断链表是否有环 List_node *find_circle_begin(List *list) ; //找到链表环的入口
链表的接口实现
#include <stdio.h> #include <stdlib.h> #include <strings.h> #include <string.h> #include "list.h" //""当前目录查找头文件 <>在标准库中找 static void *Malloc(size_t size); static List_node *create_node(void); static List_node *create_node(void) { List_node *node = NULL; 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, "the mmemory is full!\n"); exit(1); } return result; } List *init_list(void) //链表的初始化 { List *list = NULL; list = (List *)Malloc(sizeof(List)); bzero(list, sizeof(List)); //对申请的内存进行初始化(清空) return list; } void destroy_list(List **list) //连表的销毁 { //销毁步骤:(1)销毁链表节点 // (2)销毁控制信息 // (3)指针置为空 if(list == NULL || *list == NULL){ return ; } while((*list)->count){ pop_front(*list); } free(*list); *list = NULL; } Boolean push_front(List *list, int value) //头部插入 { List_node *node = NULL; if(list == NULL){ return FALSE; } node = create_node(); node->data = value; //两种情况:1.链表数目为空 if(list->count){ node->next = list->head; list->head = node; }else{ //2.node既是head也是tail list->head = list->tail = node; } list->count++; return TRUE; } Boolean 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; } Boolean pop_front(List *list) //头部删除 { List_node *p_node = NULL; if(list == NULL || list->count == ZERO){ return FALSE; } p_node = list->head; if(list->count == ONE){ list->head = list->tail = NULL; }else{ list->head = p_node->next; } free(p_node); p_node = NULL; list->count--; return TRUE; } Boolean pop_back(List *list) //尾部删除 { List_node *p_node = NULL; if(list == NULL || list->count == ZERO){ return FALSE; } p_node = list->head; if(list->count == ONE){ list->head = list->tail = NULL; free(p_node); }else{ while(p_node->next != list->tail){ p_node = p_node->next; } free(list->tail); list->tail = p_node; p_node = NULL; } list->count--; return TRUE; } void print_list(List *list) //打印链表 { List_node *p_node = NULL; if(list == NULL || list->count <= ZERO){ return ; } p_node = list->head; while(p_node != NULL){ printf("%d ", p_node->data); p_node = p_node->next; } printf("\n"); } static void swap(void *a, void *b, int length); static 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_node = NULL; List_node *q_node = NULL; if(list == NULL || list->count < 2){ return ; } 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->data, &q_node->data, sizeof(int)); } } } } void sort_list_descend(List *list) //降序 { List_node *p_node = NULL; List_node *q_node = NULL; if(list == NULL || list->count < 2){ return ; } 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->data, &q_node->data, sizeof(int)); } } } } int get_list_count(List *list) //得到连表节点个数 { if(list = NULL){ return -1; } return list->count; } List *merge_two_lists(List *list1, List *list2) //合并两个连表 { List *list3 = NULL; List_node *p_node = NULL; List_node *q_node = NULL; if(list1 == NULL && list2 == NULL){ return list3; } list3 = init_list(); p_node = list1->head; q_node = list2->head; while(p_node != NULL && q_node != NULL){ if(p_node->data <= q_node->data){ push_back(list3, p_node->data); p_node = p_node->next; }else{ push_back(list3, q_node->data); q_node = q_node->next; } } while(p_node != NULL){ push_back(list3, p_node->data); p_node = p_node->next; } while(q_node != NULL){ push_back(list3, q_node->data); q_node = q_node->next; } return list3; } List_node *find_revise_node(List *list, int num) //找到连表倒数第num个节点 { //若不知list->count,可以使用快慢指针来解决--->先让一个指针向后移动num-1步, //后 让另外一个指针和该指针一起向后移动,当该指针移动到末尾时即慢指针所在位 //置即为所找节点 #if 0 List_node *p_node = NULL; int count = 0; if(list == NULL || num <= ZERO || list->count == ZERO || num > list->count){ return NULL; } p_node = list->head; count = list->count - num; while(count--){ p_node = p_node->next; } return p_node; #endif #if 1 List_node *p_node = NULL; List_node *q_node = NULL; int count = 0; if(list == NULL || num <= ZERO){ return NULL; } p_node = list->head; q_node = list->head; count = num - 1; while(count--){ p_node = p_node->next; } while(p_node->next != NULL){ p_node = p_node->next; q_node = q_node->next; } return q_node; #endif } List_node *find_middle_node(List *list) //得到链表的中间节点 { List_node *mid_node = NULL; int count = 0; if(list == NULL){ return mid_node; } mid_node = list->head; count = list->count >> 1; while(count--){ mid_node = mid_node->next; } return mid_node; } List *reverse_list(List *list) //逆置链表 { #if 0 List *new_list = NULL; List_node *p_node = NULL; // List_node *q_node = NULL; if(list == NULL || list->count <= ONE){ return new_list; } p_node = list->head; new_list = init_list(); //q_node = new_list->head; while(p_node != NULL){ push_front(new_list, p_node->data); p_node = p_node->next; } return new_list; #endif #if 1 List_node *p_node = NULL; List_node *q_node = NULL; List_node *r_node = NULL; if(list == NULL || list->count <= ONE){ return list; } if(list->count == TWO){ list->tail->next = list->head; list->head->next = NULL; }else{ p_node = list->head; q_node = p_node->next; r_node = q_node->next; p_node->next = NULL; do{ q_node->next = p_node; p_node = q_node; q_node = r_node; r_node = r_node->next; }while(r_node != NULL); q_node->next = p_node; } swap(&list->head, &list->tail, sizeof(List_node *)); return list; #endif } List *copy_list(List *list) //链表的拷贝 { List *result = NULL; List_node *p_node = NULL; if(list == NULL){ return NULL; } result = init_list(); p_node = list->head; while(p_node != NULL){ push_back(result, p_node->data); p_node = p_node->next; } return result; } Boolean is_list_intersect(List *list1, List *list2) //判断两个链表是否有交点 { if(list1 == NULL || list2 == NULL || list1->count == ZERO || list2->count == ZERO){ return FALSE; } return list1->tail == list2->tail; #if 0 if(list1->tail == list2->tail){ return TRUE; }else{ return FALSE; } #endif } List_node *find_first_common_node(List *list1, List *list2) //找到两个链表的第一个交点 { int len = 0; int l1_len = 0; int l2_len = 0; List_node *p_node = NULL; List_node *q_node = NULL; if(list1 == NULL || list2 == NULL || list1->count == ZERO || list2->count == ZERO || is_list_intersect == FALSE){ return NULL; } l1_len = list1->count; l2_len = list2->count; p_node = list1->head; q_node = list2->head; if(l1_len >= l2_len){ len = l1_len - l2_len; while(len--){ p_node = p_node->next; } }else{ len = l2_len - l1_len; while(len--){ 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_one_node(List *list, List_node *node) //删除链表的一个节点 { //用node的next的data覆盖node的data,并让node的next指向其next的next //然后将node的next删除 List_node *p_node = NULL; if(list == NULL || node == NULL){ return ; } p_node = list->head; if(node->next != NULL){ p_node = node->next; node->data = p_node->data; node->next = p_node->next; free(p_node); list->count--; }else{ pop_back(list); } } Boolean has_circle(List *list) //判断链表是否有环 { List_node *p_node = NULL; if(list == NULL || list->count < TWO || list->tail->next == NULL){ return FALSE; } p_node = list->head; while(p_node != NULL){ if(p_node == list->tail->next){ return TRUE; } p_node = p_node->next; } return FALSE; } Boolean has_circle2(List *list, List_node **intersect); Boolean has_circle2(List *list, List_node **intersect) { List_node *p_node = NULL; List_node *q_node = NULL; if(list == NULL || list->count < TWO){ return FALSE; } p_node = q_node = list->head; while(q_node != NULL && q_node->next != NULL){ p_node = p_node->next; q_node = q_node->next->next; if(p_node == q_node){ return TRUE; } } return FALSE; } //如果函数有多个返回值,只有传入某个值指针类型,才可以将其传出 List_node *find_circle_begin(List *list) //找到链表环的入口 { List_node *p_node = NULL; if(list == NULL || list->count < TWO || list->tail->next == NULL){ return NULL; } p_node = list->head; do{ if(p_node == list->tail->next){ return p_node; } p_node = p_node->next; }while(p_node != NULL); return NULL; } List_node *find_circle_begin2(List *list); //找到链表环的入口 List_node *find_circle_begin2(List *list) //找到链表环的入口 { if(!has_circle2(list, &intersect)){ return NULL; } }
链表的测试代码如下:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include "list.h" int main(int ac, char **av) { List *list = init_list(); //链表初始化 List *list1 = init_list(); List *list2 = init_list(); List *list3 = NULL; List_node *p_node = NULL; List_node *q_node = NULL; int i = 0; int result = 0; srand(time(NULL)); for(i = 0; i < 10; ++i){ push_front(list, rand() % 100); } for(i = 0; i < 10; ++i){ push_front(list1, rand() % 100); } printf("before sort show list:\n"); print_list(list); printf("before sort show list1:\n"); print_list(list1); sort_list_ascend(list); sort_list_ascend(list1); printf("after sort show list:\n"); print_list(list); printf("after sort show list1:\n"); print_list(list1); list2 = merge_two_lists(list, list1); printf("after merge show list2:\n"); print_list(list2); printf("after merge show list:\n"); print_list(list); printf("after merge show list1:\n"); print_list(list1); printf("after reverse show list2:\n"); list3 = reverse_list(list2); printf("after reverse show list3:\n"); print_list(list3); printf("倒数第num个节点\n"); p_node = find_revise_node(list3, 5); printf("%d\n", p_node->data); //printf("中间节点\n"); //printf("删除一个节点\n"); //delete_one_node(list, ); //print_list(list); printf("判断两个链表是否有交点\n"); result = is_list_intersect(list, list1); printf("result is : %d\n", result); q_node = find_first_common_node(list, list1); printf("%d\n", p_node->data); sort_list_descend(list); print_list(list); destroy_list(&list); //链表的销毁 destroy_list(&list1); //链表的销毁 destroy_list(&list2); //链表的销毁 return 0; }
测试结果如下:
[root@localhost list]# ./main before sort show list: 75 68 13 10 17 45 10 24 60 21 before sort show list1: 43 8 32 88 52 8 51 87 36 20 after sort show list: 10 10 13 17 21 24 45 60 68 75 after sort show list1: 8 8 20 32 36 43 51 52 87 88 after merge show list2: 8 8 10 10 13 17 20 21 24 32 36 43 45 51 52 60 68 75 87 88 after merge show list: 10 10 13 17 21 24 45 60 68 75 after merge show list1: 8 8 20 32 36 43 51 52 87 88 after reverse show list2: after reverse show list3: 88 87 75 68 60 52 51 45 43 36 32 24 21 20 17 13 10 10 8 8 倒数第num个节点 13 判断两个链表是否有交点 result is : 0 13 75 68 60 45 24 21 17 13 10 10 [root@localhost list]#
相关文章推荐
- 两个链表实现集合的运算
- 单链表的逆置操作
- 【数据结构与算法】插入排序
- 【数据结构和算法】选择排序
- 【数据结构与算法】冒泡排序
- 数据结构(java语言描述)——串数组(n阶魔方)
- 大话数据结构读书笔记系列(四)栈与队列
- 重学数据结构系列之——堆及堆排序
- Java数据结构——优先级队列
- HDU 3065 AC自动机模版题
- HDU 2896 AC自动机模版题
- Java数据结构——队列
- 如何理解数据结构中的引用参数 &
- 数据结构 用单链表表示集合的并交差运算
- FFMPEG中重要的数据结构的挖掘
- FFmpeg的一些关键的数据结构(二)
- FFmpeg的一些关键的数据结构(一)
- ffmpeg主要数据结构及其之间的关系
- 数据结构(三)——双链表、链式栈、链式队列 及实现
- 数据结构(二)——单链表 、带头结点的单链表、循环链表 及其实现