#include <iostream>
#include <stack>
#include <set>
using namespace std;
struct ListNode{
int data;
ListNode* next;
};
typedef ListNode List;
struct dListNode{
int data;
dListNode* next;
dListNode* previous;
};
typedef dListNode dList;
//头插法建立双向链表,与单链表类似
void createDListHead(dList* &L){
L = new dList;
L->next = L->previous = NULL;
int val;
cin >> val;
while (val != -1)
{
dListNode* p = new dList;
p->next = L->next;
p->previous = L;
p->data = val;
L->next = p;
cin >> val;
}
}
//尾插法建立双向链表,与尾插法类似
void createDListRear(dList* &L){
L = new dList;
L->next = L->previous = NULL;
int val;
cin >> val;
dListNode* q = L;
while (val != -1)
{
dListNode* p = new dList;
p->data = val;
p->previous = q;
p->next = NULL;
q->next = p;
q = p;
cin >> val;
}
}
//删除指定值的节点,例如3->1->2->3->3->4->3,输入3,结果为1->2->4;
void deleteDLNode(dList* L){
int val;
cout << "Please input the val you want to delete: ";
cin >> val;
dListNode* p = L;
dListNode* q = NULL;
while (p->next != NULL)
{
if (p->next->data == val)
{
q = p->next;
if (p->next->next!=NULL) //与单向链表不同之处,不要忘记加判断是否为空指针
p->next->next->previous = p;
p->next = q->next;
delete q;
}
else
p = p->next;
}
}
//尾插法建立单链表
void createListRear(List* &L){
L = new List;
L->next = NULL;
ListNode* q = L;
int val;
cin >> val;
while (val != -1)
{
ListNode * p = new List;
p->data = val;
p->next = NULL;
q->next = p;
q = p;
cin >> val;
}
return;
}
//头插法建立单链表
void createListHead(List* &L){
L = new List;
L->next = NULL;
int val;
cin >> val;
while (val != -1)
{
ListNode* p = new List;
p->data = val;
p->next = L->next;
L->next = p;
cin >> val;
}
return;
}
//打印链表
template<typename T>
void printList(T *L){
T* p = L->next;
while (p != NULL)
{
cout << p->data << " -> ";
p = p->next;
}
cout << "NULL" << endl;
return;
}
//反转单链表,遍历链表,依次头插
void reverseList(List* L){
ListNode* p = L->next;
ListNode* r = p; //不要忘记记录头结点,循环结束后将它的next置为NULL 否则会形成环;
if (p == NULL) return; //同时不要忘记判断链表是否为空,否则r=L->next;r->next=NULL;会使程序崩溃;
while (p != NULL)
{
ListNode* q = p->next;
p->next = L->next;
L->next = p;
p = q;
}
r->next = NULL;
return;
}
//删除倒数第k个节点,快指针先走k,慢指针再走,快指针到达链表尾部时,慢指针到达倒数第K个节点
void getKthFromRear(List* L,int k){
ListNode* fast = L->next;
ListNode* slow = L->next;
if (L->next == NULL||k<=0) return;
int i = 1;
while (i < k) //此处可借可k=1考虑;
{
fast = fast->next;
if (fast == NULL) //当K大于链表长度时,为K%Len;
fast = L->next;
++i;
}
while (fast->next != NULL) //判断条件为fast->next==NULL,若为fast==NULL,则上个while条件为i<=k
{
fast = fast->next;
slow = slow->next;
}
cout << "The Kth from rear is: " << slow->data << endl;
return;
}
//获取中间节点
void getMid(List* L){
if (L->next == NULL) return;
ListNode* fast = L->next;
ListNode* slow = L->next;
while (fast->next!= NULL&&fast->next->next!=NULL) //fast fast->next当Len为奇数时返回Len/2+1;fast->next,fast->next->next返回Len/2;
{
fast = fast->next->next;
slow = slow->next;
}
cout << "Mid element is: " << slow->data << endl;
}
//逆序打印,采用栈
void printFromRear(List* L){
stack<int> iSak;
ListNode* p = L->next;
cout << "NULL" << " <- ";
while (p != NULL)
{
iSak.push(p->data);
p = p->next;
}
while (!iSak.empty())
{
cout << iSak.top() << " <- ";
iSak.pop();
}
cout << "Head" << endl;
}
//删除data=val的节点
void deleteElementK(List* L){
if (L->next == NULL) return;
cout << "Plese input the value you want to delete: ";
int val;
cin >> val;
ListNode* p = L;
ListNode* r = L;
while (p->next!= NULL) //要记录前一个节点,故要用p->next来判断;
{
if (p->next->data == val)
{
r = p->next;
p->next = r->next;
delete r;
//continue;
}
else //不要忽略else,否则出现连续的值得时候不能完全删除
p = p->next;
//p = p->next;
}
}
//合并两个有序链表,到L1
void mergeSortList(List *L1, List* L2){
if (L1->next == NULL)
{
L1->next = L2->next;
return;
}
if (L2->next == NULL) return;
ListNode* p1 = L1->next;
ListNode* p2 = L2->next;
ListNode* q = NULL;
if (p1->data < p2->data) //先找到两个链表中第一个较小的节点,让q指向它,不要忘记q=p1后面一句
{
q = p1;
p1 = p1->next;
}
else
{
q = p2;
p2 = p2->next;
}
L1->next = q;
while (p1 != NULL&&p2 != NULL)
{
if (p1->data < p2->data)
{
q->next = p1;
q = p1;
p1 = p1->next;
}
else
{
q->next = p2;
q = p2;
p2 = p2->next;
}
}
if (p1 != NULL)
q->next = p1;
else if (p2 != NULL)
q->next = p2;
}
//用于测试,构造有环链表,输入一个链表中的节点数据,形成环,例如1->4->6->8->5,输入6,会使5的下一个节点为6,形成环
void makeListWithCircle(List* L){
ListNode* p = L->next;
ListNode* c = NULL;
cout << "Please input the value to be circle:";
int val;
cin >> val;
while (p->next != NULL)
{
if (p->data == val&&c==NULL)
c = p;
p = p->next;
}
p->next = c;
}
//判断链表是否有环
bool hasCircle(List *L){
ListNode* p = L->next;
ListNode* q = L->next;
while (p->next != NULL&&p->next->next != NULL)
{
p = p->next->next;
q = q->next;
if (p == q)
return true;
}
return false;
}
//找到环的起点,用set容器存储已经遍历过的节点,每次遍历一个新节点就检查是否存在于set里,实现较简单
void findTheCircleBegin(List *L){
ListNode* p = L->next;
set<List*> listSet;
while (p != NULL)
{
if (listSet.count(p) == 0)
listSet.insert(p);
else
{
cout << p->data << endl;
return;
}
p = p->next;
}
cout << "Has No Crcle!" << endl;
}
//找到两个相交链表的第一个交点,若链表相交,则尾节点必相同,求出两个链表长度的差k,让长的链表先走k步,然后连个链表再一起走,相等时即为第一个节点
void findIntersectPos(List* L1, List* L2){
ListNode* p1 = L1->next;
ListNode* p2 = L2->next;
int lenth1 = 1;
int lenth2 = 1;
while (p1->next != NULL)
{
p1 = p1->next;
++lenth1;
}
while (p2->next!=NULL)
{
p2 = p2->next;
++lenth2;
}
if (p1 != p2)
{
cout << "Not Intersect!" << endl;
return;
}
p1 = L1->next;
p2 = L2->next;
int k = abs(lenth1 - lenth2);
int i = 1;
if (lenth1 >= lenth2)
{
while (i <= k)
{
p1 = p1->next;
++i;
}
}
else
{
while (i <= k)
{
p2 = p2->next;
++i;
}
}
while (p2 != p1)
{
p2 = p2->next;
p1 = p1->next;
}
cout << p1->data << endl;
}
//构造用于测试的相交链表,让L2的尾节点指向L1的某一节点
void makeIntersect(List* L1, List* L2){
ListNode* p1 = L1->next;
ListNode* p2 = L2->next;
while (p2->next != NULL)
p2 = p2->next;
int val;
cout << "Please input the value of the intersect: ";
cin >> val;
while (p1 != NULL)
{
if (p1->data == val)
break;
p1 = p1->next;
}
p2->next = p1;
}
/*int main(){
char q;
//cin >> q;
cout << "please input the datas of list, -1 to end" << endl;
while (1)
{
//List *L1 = NULL;
//List* L2 = NULL;
//createListRear(L1);
//createListRear(L2);
dList* dL1 = NULL;
dList* dL2 = NULL;
createDListHead(dL1);
createDListRear(dL2);
// mergeSortList(L1, L2);
// getKthFromRear(L1, 1);
// getMid(L1);
// reverseList(L1);
//printList(L1);
//printList(L2);
//deleteElementK(L1);
//deleteElementK(L2);
printList(dL1);
printList(dL2);
deleteDLNode(dL1);
deleteDLNode(dL2);
printList(dL1);
printList(dL2);
//cout << hasCircle(L1) << endl;
//findTheCircleBegin(L1);
//makeListWithCircle(L1);
//cout << hasCircle(L1) << endl;
//findTheCircleBegin(L1);
// printFromRear(L1);
//findIntersectPos(L1, L2);
//makeIntersect(L1, L2);
// createDListRear(dL1);
// deleteDLNode(dL1);
//createDListRear(dL2);
// printList(dL1);
//printList(dL2);
//printList(L2);
//findIntersectPos(L1, L2);
cout << "Do you want to quit? (y/n)" << endl;
cin >> q;
if (q == 'y') break;
else
cout << "please input the datas of list, -1 to end" << endl;
}
//printList(L2);
return 0;
}*/