链表的相关操作函数

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode{
	int data;
	struct LNode* next;
}LNode,*LinkList;

//创建没有头结点的单链表,如果没有元素则单链表的head=NULL
LinkList create_link()
{
	LinkList head,newNode,preNode;
	int x;
	head=(LinkList)malloc(sizeof(LNode));
	preNode=head;
	scanf("%d",&x);
	while(x!=-1)
	{
		newNode=(LinkList)malloc(sizeof(LNode));
		newNode->data=x;
		preNode->next=newNode;
		preNode=newNode;
		scanf("%d",&x);
	}
	preNode->next=NULL;
	preNode=head;
	head=head->next;
	free(preNode);
	return head;
}

//顺序打印单链表
void print_link(LinkList head)
{
	LinkList h;
	if(head==NULL)
		return;
	h=head;
	while(h)
	{
		printf("%6d",h->data);
		h=h->next;
	}
	printf("\n");
}
//获得单链表的长度
int get_link_length(LinkList head)
{
	LinkList h;
	int len=0;
	if(head==NULL)
		return len;
	h=head;
	while(h)
	{
		len++;
		h=h->next;
	}
	return len;
}
//删除单链表中data值为num的结点
LinkList delete_link_node(LinkList head,int num)
{
	LinkList curNode,nextNode;
	if(head==NULL)
		return head;
	//delete the first node
	curNode=head;
	if(head->data==num)
	{
		if(head->next==NULL)
		{
			free(head);
			head=NULL;
		}
		else
		{
			head=head->next;
			free(curNode);
		}
		return head;
	}
	//delete the mid node
	while(curNode->next && curNode->next->data!=num)
		curNode=curNode->next;
	if(curNode->next==NULL)//num is not exsite in link
		return head;
	nextNode=curNode->next;
	curNode->next=nextNode->next;
	free(nextNode);
	return head;
}

//向有序单链表中插入num
LinkList insert_link_node(LinkList head, int num)
{
	LinkList curNode,newNode,nextNode;
	if(head==NULL)//link not exist
		return head;
	if(head->data>num)//插入位置为第一个结点
	{
		newNode=(LinkList)malloc(sizeof(LNode));
		newNode->data=num;
		newNode->next=head->next;
		head=newNode;
		return head;
	}
	//插入位置为中间结点或尾结点
	curNode=head;
	nextNode=curNode->next;
	while(nextNode && nextNode->data<num)
	{
		curNode=nextNode;
		nextNode=nextNode->next;
	}
	newNode=(LinkList)malloc(sizeof(LNode));
	newNode->data=num;
	newNode->next=nextNode;
	curNode->next=newNode;
	return head;
}


//逆序打印单链表
void reverse_print_link(LinkList head)
{
	//static LinkList h = head;
	if(head==NULL)
		return;
	else
	{
		reverse_print_link(head->next);
		//	if (h != head)
		printf("%6d",head->data);
	}
}

//逆置单链表
LinkList reverse_link(LinkList head)
{
	LinkList preNode,curNode,nextNode;
	preNode=head;
	curNode=preNode->next;
	if(head==NULL || head->next==NULL)
		return head;
	while(curNode)
	{
		nextNode=curNode->next;
		curNode->next=preNode;
		preNode=curNode;
		curNode=nextNode;
	}
	head->next=NULL;
	head=preNode;
	return head;
}

//返回倒数第k个结点
LinkList find_Kth_toTail(LinkList head,int k)
{
	LinkList pAhead,pBehind;
	int i=0;

	if(head==NULL || k<=0)
		return NULL;
	pAhead=head;
	pBehind=head;
	while(pAhead && i<k)
	{
		pAhead=pAhead->next;
		i++;
	}
	if(pAhead==NULL && i<k)
		return NULL;
	if(i==k)
		return head;
	while(pAhead)
	{
		pAhead=pAhead->next;
		pBehind=pBehind->next;
	}
	return pBehind;
}

//返回单链表的中间节点,如果是偶数个结点,返回前一个,奇数个结点,返回中间的结点
LinkList find_mid_node(LinkList head)
{
	LinkList pFast,pSlow;
	if(head==NULL)
		return NULL;
	if(head->next==NULL || head->next->next==NULL)
		return head;
    pFast=head;
	pSlow=head;
	while(pFast->next && pFast->next->next)
	{
        pSlow=pSlow->next;
		pFast=pFast->next;
		pFast=pFast->next;
	}
	return pSlow;
}

//合并两个有序单链表
LinkList merge_link(LinkList head1,LinkList head2)
{
	LinkList h1,h2,h3,h;
	if(head1==NULL && head2==NULL)
		return NULL;
	if(head1==NULL)
		return head2;
	if(head2==NULL)
		return head1;
	h1=head1;
	h2=head2;
	if(h1->data<=h2->data)
	{
		h3=h1;
		h1=h1->next;
	}
	else
	{
		h3=h2;
		h2=h2->next;
	}
	h=h3;
	while(h1!=NULL && h2!=NULL)
	{
		if(h1->data<=h2->data)
		{
            h3->next=h1;
			h3=h1;
			h1=h1->next;
		}
		else
		{
			h3->next=h2;
			h3=h2;
			h2=h2->next;
		}
	}
	h3->next= h1==NULL? h2 : h1;
    return h;
}

//对单链表进行归并排序
LinkList merge_sort_link(LinkList head)
{
    LinkList midNode,head2;
	if(head==NULL)
		return NULL;
	if(head->next==NULL)
		return head;
	midNode=find_mid_node(head);
	head2=midNode->next;
	midNode->next=NULL;
	head=merge_sort_link(head);
	head2=merge_sort_link(head2);
	return merge_link(head,head2);
}

LinkList create_circle_link()
{
	LinkList head,newNode,preNode;
	int x;
	head=(LinkList)malloc(sizeof(LNode));
	preNode=head;
	scanf("%d",&x);
	while(x!=-1)
	{
		newNode=(LinkList)malloc(sizeof(LNode));
		newNode->data=x;
		preNode->next=newNode;
		preNode=newNode;
		scanf("%d",&x);
	}
	preNode->next=head->next->next;
	//preNode->next=preNode;
	preNode=head;
	head=head->next;
	free(preNode);
	return head;
}

bool is_exist_circle(LinkList head)
{
	LinkList slow,fast;
	slow=head;
	fast=head;
	if(head==NULL || head->next==NULL)
		return false;
	while(fast!=NULL && fast->next!=NULL)
	{
		slow=slow->next;
		fast=fast->next->next;
		if(slow==fast)
			return true;
	}
	return false;
}

LinkList find_loop_port(LinkList head) 
{     
	LinkList slow = head, fast = head;
    while ( fast && fast->next ) 
	{       
		slow = slow->next;        
		fast = fast->next->next;         
		if ( slow == fast ) break;    
	}     
	if (fast == NULL || fast->next == NULL) 
		return NULL;     
	slow = head;     
	while (slow != fast)     
	{          
		slow = slow->next;          
		fast = fast->next;    
	}    
	return slow; 
}

//判断两个单链表是否相交,如果相交返回相交点,如果不相交返回NULL
LinkList test_intersect(LinkList head1,LinkList head2)
{
    bool is_loop1=false,is_loop2=false;

	if(head1==NULL || head2==NULL)
		return NULL;
	
	is_loop1=is_exist_circle(head1);
	is_loop2=is_exist_circle(head2);
	if(is_loop1 && !is_loop2)
		return NULL;
	if(!is_loop1 && is_loop2)
		return NULL;
	if(!is_loop1 && !is_loop2)//两个链表都没有环
	{
		LinkList p1,p2;
		int len1,len2,i;
		len1=get_link_length(head1);
		len2=get_link_length(head2);
		p1=head1;
		p2=head2;
		if(len1>len2)
		{
			i=len1-len2;
			while(i>0)
			{
				i--;
				p1=p1->next;
			}
		}
		else if(len1<len2)
		{
			i=len2-len1;
			while(i>0)
			{
				i--;
				p2=p2->next;
			}
			
		}
		while(p1!=p2 && p1!=NULL && p2!=NULL)
		{
			p1=p1->next;
			p2=p2->next;
		}
		if(p1==p2)
			return p1;
		else
			return NULL;
 
	}
    if(is_loop1 && is_loop2)//两个链表都有环
	{
		LinkList port1,port2;
		port1=find_loop_port(head1);
		port2=find_loop_port(head2);
		if(port1==NULL || port2==NULL)
		{
			printf("error\n");
			return NULL;
		}
        if(port1==port2)//在环之前相交?
		{
            int len1=0,len2=0,i;
			LinkList p1,p2;

			p1=head1;
			while(p1!=port1)
			{
				len1++;
				p1=p1->next;
			}
			p2=head2;
			while(p2!=port2)
			{
				len2++;
				p2=p2->next;
			}


			p1=head1;
			p2=head2;
			if(len1>len2)
			{
				i=len1-len2;
				while(i>0)
				{
					i--;
					p1=p1->next;
				}
			}
			else if(len1<len2)
			{
				i=len2-len1;
				while(i>0)
				{
					i--;
					p2=p2->next;
				}

			}
			while(p1!=p2 && p1!=port1 && p2!=port2)
			{
				p1=p1->next;
				p2=p2->next;
			}
			if(p1==p2)
				return p1;
			else
				return NULL;
		}
		else//判断是否在环内相交
		{
            LinkList p;
			p=port1;

			port1=port1->next;
			while(port1!=port2 && port1!=p)
				port1=port1->next;
			if(port1==port2)
				return port1;
			else return NULL;
		}
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值