#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE (1)
#define FALSE (0)
#define ZERO (0)
#define ONLY_ONE (1)
typedef unsigned char Boolean;
typedef struct list{
struct node *head;
struct node *tail;
int count;
}*List;
typedef struct node{
int data;
struct node *next;
}*p_node;
static void *Malloc(size_t length);
List init_list(void);
void destroy(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 sort_list_ascend(List list);
void sort_list_descent(List list);//节点由大到小排列
List merge_two_lists(List list1,List list2);
List merge_two_lists_recure(List list1,List list2);
p_node find_revise_node(List list,int num);//找到链表的倒数第num个节点
p_node find_mid_node(List list);
List reverse_list(List list);//逆置链表
void reverse_show_list(List list);
List list_dump(List list);//拷贝链表
Boolean is_list_intersect(List list1,List list2);//判断链表是否相交
p_node get_common_node(List list1,List list2);
void delete_one_node(List list,int value);//O(1)时间复杂度删除节点
Boolean has_circle(List list);//判断是否有环
p_node find_circle_first_node(List list);//找到环的第一个节点
void swap(p_node p,p_node q);
//接口实现
/////////////////////////////////////////////////////////////////
<pre name="code" class="cpp">//模块化思想,Malloc函数里,分配内存,顺便判断是否分配成功
static void *Malloc(size_t length)
{
void *result;
result = malloc(length);
if(result == NULL){
fprintf(stderr,"the stack is full");
return ;
}
}
//初始化链表
List init_list()
{
List list;
list = (List)Malloc(sizeof(struct list));
bzero(list,sizeof(struct list));
return list;
}
//销毁链表
void destroy(List *list)
{
if(list == NULL && *list == NULL){
return ;
}
//删除节点信息
while((*list)->count){
pop_front(*list);
}
free(*list);
*list = NULL;
//p_node p = (*list)->head;
//while((*list)->head != (*list)->tail){
// (*list)->head = p->next;
// bzero(p,sizeof(struct list));
// p = (*list)->head;
//}
//bzero((*list),sizeof(struct list));
}
//头插法
Boolean push_front(List list,int value)
{
if(list == NULL){
return FALSE;
}
//要插入的节点p
p_node p = (p_node)Malloc(sizeof(struct node));
p->data = value;
//链表节点为0时,首尾都等与节点p
if(list->count == ZERO){
p->next = NULL;
list->tail = list->head = p;
//p插入到头指针前,然后另头指针指向p
}else{
p->next = list->head;
list->head = p;
}
list->count++;
return TRUE;
}
//尾插法
Boolean push_back(List list,int value)
{
p_node p;
if(list == NULL){
return FALSE;
}
p = (p_node)Malloc(sizeof(struct node));
if(list->count == ZERO){
p->data = value;
p->next = NULL;
list->tail = list->head = p;
}else{
p->data = value;
p->next = NULL;
list->tail->next = p;
list->tail = p;
}
list->count++;
return TRUE;
}
//头部弹出
Boolean pop_front(List list)
{
if(list->head == NULL||list->count == 0){
return FALSE;
}
p_node p;
//如果只有一个节点,那么head和tail都置空
if(list->count == ONLY_ONE){
p = list->head;
list->head = list->tail = NULL;
}else{
//让p指向head,然后head指向head->next
p = list->head;
list->head = list->head->next;
}
//释放p
free(p);
list->count--;
return TRUE;
}
//尾部弹出
Boolean pop_back(List list)
{
if(list->head == NULL||list->count == 0){
return FALSE;
}
p_node tmp;
p_node p = list->head->next;
if(p->next == NULL){
p = list->head;
list->head = list->tail = NULL;
list->count--;
return TRUE;
}
while(p->next->next){
p = p->next;
}
tmp = p->next;
p->next = NULL'
free(p);
list->tail = p;
list->count--;
return TRUE;
}
//输出链表信息
void show_list(List list)
{
p_node p = list->head;
if(list != NULL && list->count != ZERO){
while(p){
printf("%d ",p->data);
p = p->next;
}
}
printf("\n");
}
//判断是否有环
Boolean has_circle(List list,p_node *p)
{
if(list == NULL || list->count == 1){
return FALSE;
}
//分别定义快慢指针,快指针跑得速度是慢指针的两倍
p_node fast_node = list->head;
p_node slow_node = list->head;
for(;;){
fast_node = fast_node->next->next;
slow_node = slow_node->next;
//如果快慢指针相遇,那么说明相交
if(fast_node == slow_node){
*p = fast_node;
return TRUE;
}
else if(fast_node == NULL || fast_node->next == NULL)
return FALSE;
}
}
void delete_one_node(List list,int value)//O(1)时间复杂度删除节点
{
//把当前节点数据域和它的下一个节点互相交换,然后删除下一个节点
p_node p = list->head->next;
if(list == NULL){
return ;
}
while(p->data != value && p){
p = p->next;
}
if(p != list->tail){
p->data = p->next->data;
p->next = p->next->next;
}
else
pop_back(list);
list->count--;
}
<img src="https://img-blog.youkuaiyun.com/20151127230018948?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
//找到两个链表的交点.两个节点数量相减得x,然后另链表节点数量多的跑x个单位,然后两者一起跑
p_node get_common_node(List list1,List list2)
{
p_node p = list1->head;
p_node q = list2->head;
int c;
if(!is_list_intersect(list1,list2)){
return NULL;
}
if(list1->count > list2->count){
c = ((list1->count) - (list2->count));
while(c--){
p = p->next;
}
}
else{
c = ((list2->count) - (list1->count));
while(c--){
q = q->next;
}
}
while(p != q){
p = p->next;
q = q->next;
}
return p;
}
//两者尾节点相同说明相交
Boolean is_list_intersect(List list1,List list2)//判断链表是否相交
{
if(list1 == NULL || list2 == NULL)
return FALSE;
return list1->tail == list2->tail;
}
//递归输出节点信息,当p->next为NULL时停止
static void rev_show_node(p_node p)
{
if(p->next != NULL){
rev_show_node(p->next);
}
printf("%d ",p->data);
}
//调用rev_show_node输出链表信息
void reverse_show_list(List list)
{
if(list == NULL)
return ;
rev_show_node(list->head);
}
//通过判断是否是环二级指针得到交点intersect,把从intersect开始作为一个单链表,//从head开始到intersect作为第二个单链表//调用相交函数get_common_node得到相交节点
p_node find_circle_first_node(List list)//找到环的第一个节点{
//
List list2; List list1; p_node p = list->head; p_node intersect = NULL;
//判断是否有环,并且找到快慢指针交点
has_circle(list,&intersect); if(list == NULL){ return NULL; }
//把环放入链表1中
while(intersect->next != intersect){ push_front(list1,intersect->data); intersect = intersect->next; }
push_front(list1,intersect->data);
//从头节点到快慢指针交点放入链表2中
while(p != intersect){ push_front(list2,p->data); p = p->next; }
//找到要求节点
return get_common_node(list1,list2);}
//翻转链表,新建一个链表,然后头插
List reverse_list1(List list)//逆置链表{
//链表节点p等于链表头
p_node p = list->head; if(list == NULL || list->count < 2) { return NULL; } List L; L = init_list(); while(p){
//每次都是用原始链表节点的下一个,做新链表的头节点
push_front(L,p->data); p = p->next; }
return L;}
//把控制信息拷贝,然后通过memcpy拷贝数据域和链域
List list_dump(List list)//拷贝链表
{
List L = (List)Malloc(sizeof(struct list));
p_node q = NULL;
p_node p = list->head->next;
while(p != list->tail){
q = (p_node)Malloc(sizeof(struct node));
L->head = list->head;
L->count = list->count;
p = list->head->next;
q = L->head->next;
memcpy(p,q,sizeof(struct list));
}
memcpy(L->tail,q,sizeof(struct list));
return L;
}
//前两个节点要分开逆置,先把head赋给tail,然后另p赋给head
List reverse_list(List list)//逆置链表
{
if(list->count == 1 || list == NULL){
return NULL;
}
p_node p = list->head->next;
p_node q = p->next;
p_node q_next = NULL; //先把头节点和第二个节点逆置
p->next = list->head;
list->head->next = NULL;
list->tail = list->head;
if(q == NULL)
return list;
if(q){
q_next = q->next;
}
while(q){
q->next = p;
p = q;
q = q_next;
if(q == NULL){
break;
}
else
q_next = q_next->next;
}
list->head = p;
return list;
}
//swap的泛型编程,(unsigned long)&(((p_node)0)->next)表示链表的数据域的长度
void swap(p_node p,p_node q)
{
p_node tmp = (p_node)Malloc(sizeof(struct node));
memcpy(tmp,p,(unsigned long)&(((p_node)0)->next));
memcpy(p,q,(unsigned long)&(((p_node)0)->next));
memcpy(q,tmp,(unsigned long)&(((p_node)0)->next));
}
//冒泡排序,从头节点开始与它的后面所有节点做比较,如果它的下一个结构体数据域小于它,那么二者交换.然后头节点增加一个单位,以此类推直到倒数第二个节点.
void sort_list_ascend(List list)//节点由小到大排列
{
if(list == NULL){
return ;
}
p_node p = list->head;
p_node q = p->next;
while(p->next){
while(q){
if(p->data > q->data){
swap(p,q);
}
q = q->next;
}
p = p->next;
q = p->next;
}
}
//与从小到大相似
void sort_list_descent(List list)//节点由大到小排列
{
if(list == NULL){
return ;
}
p_node p = list->head;
p_node q = p->next;
while(p->next){
while(q){
if(p->data < q->data){
swap(p,q);
}
q = q->next;
}
p = p->next;
q = p->next;
}
}
//快慢指针,一个指针是另一个的一倍,当快指针的下一个或者它本身是NULL时,那么慢指针就是中点.
//无论奇偶,都是第n/2个
p_node find_mid_node(List list)
{
p_node p = list->head;
p_node q = list->head;
while(p->next && p->next->next){
p = p->next->next;
q = q->next;
}
return q;
}
//找到倒数第num个节点
p_node find_revise_node(List list,int num){
//跑num次p = p->next.然后p和q一起跑,当p为空时,说明q就是在倒数第num上
p_node p = list->head;
p_node q = list->head;
if(list == NULL || num == 0){
return NULL;
}
while(num--){
p = p->next;
}
while(p){
q = q->next;
p = p->next;
}
return q;
}
int main(int argc,char *argv[]){
List list;
List L;
list = init_list();
int i = 0;
for(;i < 10;++i){
push_front(list,rand()%30);
}
sort_list_ascend(list);
show_list(list);
delete_one_node(list,2 show_list(list);
//L = reverse_list1(list);
//show_list(L);
//reverse_show_list(list);
destroy(&list);
//destroy(&L);
//List list1;
//List list2;
//int i = 0;
//list1 = init_list();
//list2 = init_list();
//for(;i < 10; ++i){
// push_front(list1,rand()%200);
//}
//for(i = 0;i < 10; ++i){
// push_front(list2,rand()%200);
//}
//sort_list_ascend(list1);
//sort_list_ascend(list2);
//show_list(list1);
//show_list(list2);
//list = merge_two_lists(list1,list2);
//show_list(list);
//p_node p; //p_node q;
//int i = 0;
//for(;i < 10; ++i){
// push_front(list,(rand())%50);
//}
//show_list(list);
//p = find_revise_node(list,2);
//printf("%d\n",p->data);
//q = find_mid_node(list);
//printf("%d\n",q->data);
//sort_list_ascend(list);
//list = reverse_list(list);
//show_list(list);
//destroy(&list);
return 0;
}