对于 数据结构->链式表->单向链表 的增删改查是比较简单的,今天我们来说一下其他的内容;
1.如何快速找到单向链表的中间节点;
使用快慢指针,快指针每次走两步,慢指针每次走一步,由数学关系可知,快指针走到最后一个节点,慢指针走到中间节点(节点有奇数个)(偶数个时<4个><慢指针走到第二个节点>)
2.如何查找倒数第K个节点:
使用快慢指针,让快指针比慢指针多走K个节点,然后两节点一起向后走,注意判断NULL的情况;
3.如何进行单向链表的倒置;
将第一个节点与头节点断开,再将节点依次用头插法插入,代码如下:
int turnLinklist(Linknode *pHead)
{
Linknode *ptemp1 = NULL:
Linknode *ptemp2 = NULL:
ptemp1 = pHead->pnext;
pHead->pnext = NULL;
ptemp2 = ptemp1;
while(pTemp != NULL)
{
ptemp1 = ptemp1->pnext;
ptemp2->pnext = NULL;
pHead->pnext = ptemp2;
ptemp2 = ptemp1;
}
return 0;
}
4.如何对单向链表进行冒泡排序;
用两个指针,指向链表,一个指在第一个节点,一个指在第二个节点,两个指针同时向后走,比较大小且交换,再用第三个指针记录每次后一个指针的最终位置,下一次前一个指针走到这里就停止掉。代码如下:
int Bubbleslist(Listnode *pHead)
{
Linknode *before = NULL;
Linknode *after = NULL;
Linknode *post = NULL;
char *ptemp = NULL;
if(pHead->pnext == NULL || pHead->pnext->pnext == NULL)
{
return 0;
}
while(1)
{
before = pHead->pnext->pnext;
after = pHead->pnext;
while(before != post)
{
if(after->data > before->data) //从小到大排序
{
ptemp = before->data;
before->data = after->data;
after->data = ptemp;
}
before = before->pnext;
after = after->pnext;
}
post = after;
}
return 0;
}
5.如何对单向链表进行选择排序;
用两个指针(post,swp)同时指在第一个节点,用一个指针(ptemp)向后走,如果找到一个数大于swp指的节点数据,就让swp指向这个新数据的节点,如此下去,直至走完,再比较post和swp是否相同,不相同就进行交换,下一次遍历让post指针指在第二个节点,从而完成排序。代码如下:
int selectLinklist(LinkNode *pHead)
{
LinkNode *temp = NULL;
LinkNode *first = NULL;
LinkNode *temp1 = NULL;
DataType tempnum = 0;
if(pHead->pNext == NULL)
{
return 0;
}
first = pHead->pNext;
while(first->pNext != NULL)
{
temp = first;
temp1 = first->pNext;
while(temp1 != NULL)
{
if(temp1->Data < temp->Data)
{
temp = temp1;
}
temp1 = temp1->pNext;
}
if(temp != first)
{
tempnum = first->Data;
first->Data = temp->Data;
temp->Data = tempnum;
}
first = first->pNext;
}
return 0;
}
选择排序和冒泡排序相比,选择排序的交换次数更少,时间上能优化一点;
6.不知道头结点,如何删除该节点;
将下一个节点的数据放在当前节点,然后删除下一个节点,并将本节点和下下个节点连接起来;
7.如何判断单向链表是否有环;
使用快慢指针,快指针走两步,慢指针走一步,当快慢指针相遇时则表明有环;
8.若单向链表有环,如何求环长;
从相遇的节点往后走,并计数,再一次走到相遇的节点,计数次数就是环长;
9.若单向链表有环,如何求环入口;
定义两个指针,一个从开头的位置往后走,一个从相遇的位置往后走,当这两指针相遇时,则该节点为环入口的节点;