链表经典应用(一)

链表相关算法

  • 结构体
  • 交叉合并(带头结点)
  • 求链表的中间结点(快慢指针法)
  • 逆置单链表(带头结点)
  • 判断回文链表(带头结点):取中间结点+逆置+比对
  • 判断环形链表(快慢指针法)
  • 判断相交链表,返回相交结点


结构体

typedef struct LNode{
	int data;
	struct LNode *next;
}LNode,*LinkList; 

交叉合并(带头结点)

//交叉合并(带头结点) 
void Merge(LinkList &A,LinkList B){
	LNode *pa,*pb,*r;
	pa = A->next;
	pb = B->next;
	r = A;
	A->next = NULL;//将头结点摘下
	
	while(pa && pb){
		r->next = pa;
		r = pa;
		pa = pa->next;
		r->next = pb;
		r = pb;
		pb = pb->next;
	} 
	if(pa){
		r->next = pa;
	}else{
		r->next = pb;
	}
	B->next = NULL;
	free (B);
}

求链表的中间结点(快慢指针法)

  • 当为奇数个结点时,fast->next = NULL,slow = 中间结点;
  • 当为偶数个结点时,fast = NULL,slow = 正中间偏右的结点;
LNode* midNode(LNode *head){
	LNode *slow = head;
	LNode *fast = head;
	while(fast && fast->next){
		slow = slow->next;
		fast = fast->next->next;
	} 
	return slow;
}

逆置单链表(带头结点)

LNode* ReverseList(LNode *head){
	LNode *pre = NULL;
	LNode *curr = head->next;
	while(curr){
		LNode *temp = curr->next;
		curr->next = pre;
		pre = curr;
		curr = temp;
	}
	head->next = pre;
	return head;
} 

判断回文链表(带头结点):取中间结点+逆置+比对

  • 取中间结点,逆置
  • 将逆置后的后半段链表与前半段链表进行比对
bool isPalindrone(LNode *head){
	LNode *mid = midNode(head);
	// 如果不带头结点,接下来两行代码无需加next 
	LNode *head2 = ReverseList(mid)->next;
	head = head->next;
	while(head2){
		if(head->data != head2->data){
			printf("不是回文链表\n");
			return false;
		}
		head = head->next;
		head2 = head2->next;
	}
	printf("是回文链表\n");
	return true;
} 

判断环形链表(快慢指针法)

快慢指针法,又称“兔子乌龟法”,兔子、乌龟在链表上移动,兔子跑得比乌龟快,从同一结点开始,

  • 若有环,兔子会先于乌龟进入环,并且一直在环内移动;等到乌龟进入环时,由于兔子速度快,兔子一定在某个时刻与乌龟相遇(俗称“套环、套圈”)
  • 若没有环,兔子将一直处于乌龟前方
bool hasCycle(LNode *head){
	LNode *fast = head;
	LNode *slow = head;
	if(head==NULL || head->next == NULL){
		return false;
	}
	while(fast && slow && fast->next){
		fast = fast->next->next;
		slow = slow->next;
		if(fast==slow){
			printf("有环\n"); 
			return true;
		}
	}
	printf("没有环\n");
	return false;
} 

判断相交链表,返回相交结点

  • 两链表长度相等,一步步前行,总会有一点相遇
  • 两链表长度不等,则短链和长链上的两个指针在逻辑上相互追赶,总有一点相遇

(写到这里,笔者突然觉得有点浪漫,如果两个人的命运注定相交,那么无论何种方式,总能相遇。写完了觉得自己的发言很离谱哈哈哈,没关系的)

LNode * getIntersectionNode(LNode *headA,LNode *headB){
	LNode *p = headA;
	LNode *q = headB;
	while(p!=q){
		p = p?p->next:headB;
		q = q?q->next:headA;
	}
	return p;
} 

创作不易,希望留下你的小赞赞哦~ 谢谢宝子~

你可能感兴趣的:(手搓数据结构课程代码,算法,c++,数据结构,c语言,后端)