链表是数据结构中的基础,在这里我会将一些链表操作的原理和代码列出:
1.两个链表中的数字相加,比如链表A中存的数字依次是1111111111,链表B中存的数字依次是99999,那么我们要得到一个新的链表C,C中存的是1111111111+99999,也就是1112111110作为最终结果存在C中。这个的思想主要是链表的反转,思考一下,数字相加,都是从低位开始相加,而在链表之中头节点存的是高位数,所以链表的反转是解决问题的关键。一共需要反转三次,ABC都需要反转一次,A,B首先反转相加,大于10时记录进位,向前推进,直至两个链表都结束,带到的心链表反转,为最后结果C。
/*将两个链表相加 越靠前位数越大*/
#include<iostream>
#include<List>
using namespace std;
struct Node
{
Node * pNext;
int num;
};
void CreateNode(Node * * pTop,Node * * pEnd,int num)
{
Node * p = new Node;
p->pNext = NULL;
p->num = num;
if(*pTop == NULL)
{
*pTop = p;
*pEnd = p;
}
else
{
(*pEnd)->pNext = p;
*pEnd = p;
}
}
int main()
{
Node * pTop1 = NULL,*pEnd1 = NULL,*temp1 = NULL;
Node * pTop2 = NULL,*pEnd2 = NULL,*temp2 = NULL;
Node * pTop = NULL,*pEnd = NULL;
Node * temp = NULL,*pTemp = NULL;
bool jin = false;
int r = -1;
//创建数字链表
for(int i = 0;i < 10;i++)
{
CreateNode(&pTop1,&pEnd1,1);
}
for(int i = 0;i < 5;i++)
{
CreateNode(&pTop2,&pEnd2,9);
}
temp = pTop1;
//反转第一个链表
while(1)
{
temp1 = temp->pNext;
temp->pNext = temp2;
temp2 = temp;
temp = temp1;
if(temp == NULL)
{
break;
}
}
//反转第二个链表
pTemp = temp2;
temp2 = NULL;
temp = pTop2;
while(1)
{
temp1 = temp->pNext;
temp->pNext = temp2;
temp2 = temp;
temp = temp1;
if(temp == NULL)
{
break;
}
}
//对应位置相加直至其中一个链表走到头
while(1)
{
if(pTemp == NULL || temp2 == NULL)
{
break;
}
r = pTemp->num + temp2->num;
if(jin == true)
{
r = r + 1;
}
if(r >= 10)
{
r = r - 10;
jin = true;
}else
{
jin = false;
}
CreateNode(&pTop,&pEnd,r);
pTemp = pTemp->pNext;
temp2 = temp2->pNext;
}
//如果两个链表都走完
if(temp2 == NULL && pTemp == NULL)
{
if(jin == true)
{
CreateNode(&pTop,&pEnd,1);
}
}
//其中一个没有走完继续
else
{
if(temp2 != NULL)
{
temp = temp2;
}else if(pTemp != NULL)
{
temp = pTemp;
}
//将剩余链表加进来
while(1)
{
if(temp == NULL)
{
break;
}
r = temp->num;
if(jin == true)
{
r += 1;
if(r >= 10)
{
jin = true;
r -= 10;
}else
{
jin = false;
}
}
CreateNode(&pTop,&pEnd,r);
temp = temp->pNext;
}
}
//将得到链表反转
temp = pTop;
temp2 = NULL;
pEnd = temp;
while(1)
{
temp1 = temp->pNext;
temp->pNext = temp2;
temp2 = temp;
temp = temp1;
if(temp == NULL)
{
break;
}
}
pTop = temp2;
return 0;
}
2.链表回文判断,将链表一分为二,且将后半部分进行链表倒转,然后以原链表尾节点和原链表头节点为起始点,开始逐次比较,如果直至相同节点相遇为止数字都相同,说明是回文链表,否则不是回文。
/*判断链表是否为回文结构,不借助栈*/
#include<iostream>
#include<List>
using namespace std;
struct Node
{
Node * pNext;
int num;
};
void CreateNode(Node * * pTop,Node * * pEnd,int num)
{
Node * p = new Node;
p->pNext = NULL;
p->num = num;
if(*pTop == NULL)
{
*pTop = p;
*pEnd = p;
}
else
{
(*pEnd)->pNext = p;
*pEnd = p;
}
}
int main()
{
Node * pTop = NULL,* pEnd = NULL,*temp = NULL,*temp1 = NULL,*temp2 = NULL,*temp3 = NULL;
int length = 20;
bool flag = true;
for(int i = 1;i <= 10;i++)
{
CreateNode(&pTop,&pEnd,i);
}
for(int i = 10;i >= 1;i--)
{
CreateNode(&pTop,&pEnd,i);
}
//将链表从中间分为两部分
temp = pTop;
for(int i = 1;i <= (length+1)/2 - 1;i++)
{
temp = temp->pNext;
}
temp1 = temp->pNext;
//链表倒转操做 下同
while(1)
{
temp3 = temp1->pNext;
temp1->pNext = temp2;
temp2 = temp1;
temp1 = temp3;
if(temp1 == NULL)
{
break;
}
}
//进行回文链表的判断
temp1 = pTop;
for(int i = 0;i < length/2;i++)
{
if(temp1->num != temp2->num)
{
flag = false;
break;
}
}
if(flag == true)
{
cout << "true" << endl;
}else
{
cout << "false" << endl;
}
//恢复原链表
temp1 = temp2;
temp2 = NULL;
while(1)
{
temp3 = temp1->pNext;
temp1->pNext = temp2;
temp2 = temp1;
temp1 = temp3;
if(temp1 == NULL)
{
break;
}
}
temp->pNext = temp2;
return 0;
}
3.删除链表链表之中重复元素,比如我有一个链表之中存的时0-6循环存储的,我想对其进行操作,直至所有元素都不重复,只剩下0-6之中的数字存在,这个操作看似简单,但是要注意陷阱,就是为元素的处理。这里,我的链表为元素是最后一个元素,在我们的循环判断时,需要向后走两个位置进行比较,所以,当结束后需要对尾元素ji'n及逆行单独检查。
/*删除重复链表*/
#include<iostream>
#include<List>
using namespace std;
struct Node
{
Node * pNext;
int num;
};
void CreateNode(Node * * pTop,Node * * pEnd,int num)
{
Node * p = new Node;
p->pNext = NULL;
p->num = num;
if(*pTop == NULL)
{
*pTop = p;
*pEnd = p;
}
else
{
(*pEnd)->pNext = p;
*pEnd = p;
}
}
int main()
{
Node * pTop = NULL, * pEnd = NULL, * temp = NULL, * pTemp = NULL, * jTemp = NULL;
bool flag = false;
int num;
for(int i = 0;i < 20;i++)
{
CreateNode(&pTop,&pEnd,i%7);
}
temp = pTop;
while(1)
{
pTemp = temp->pNext;
if(pTemp->pNext == NULL)
{
pEnd = pTemp;
temp = pTop;
num = pTemp->num;
while(temp->pNext->pNext != NULL)
{
if(temp->pNext->num == num)
{
flag = true;
}
temp = temp->pNext;
}
if(flag == true)
{
delete pTemp;
pEnd = temp;
pEnd->pNext = NULL;
}
break;
}
if(temp != NULL)
{
num = temp->num;
while(1)
{
if(temp->pNext == NULL)
{
break;
}
if(temp->pNext->num == num)
{
jTemp = temp->pNext;
temp->pNext = temp->pNext->pNext;
delete jTemp;
}
temp = temp->pNext;
if(temp == NULL)
{
break;
}
}
}
temp = pTemp;
}
temp = NULL;
return 0;
}