6.逆值/翻转单链表
思想同从头打印链表一样,但应注意在反向连接链表时的指向问题
void ListTranspose(ListNode **ppList,ListNode *pList)//转置单链表
{
assert(ppList);
if((*ppList == NULL)||((*ppList)->next == NULL))
return;
//当链表没有节点和只有一个节点的时候,转置不改变
if(pList->next != NULL) //
ListTranspose(ppList,pList->next);
else
{
*ppList = pList;//找到最后一个节点,并用头节点指向
return;
}
(pList->next)->next = pList; //
pList->next = NULL;
}
7. 单链表排序(冒泡排序)
冒泡排序是两两比较,N个数,需要N-1趟,每一趟可以找出最大的数放在这一趟的最右边:
void ListBubb(ListNode **ppList)//冒泡排序
{
assert(ppList);
if(*ppList == NULL)//链表为空时,直接返回
return;
ListNode *head = *ppList;//每次一趟从头节点开始
ListNode *tail = NULL; //用于结束标志,每一趟后tail向前一个节点挪
while((*ppList)->next != tail)
{
head = *ppList;
while(head->next != tail)
{
if((head->data) > (head->next->data))
{
DataType tmp = head->data;
head->data = head->next->data;
head->next->data = tmp;
}
head = head->next;
}
tail = head;
}
}
8.合并两个有序链表,合并后依然有序
最简单的方法就是用第一个链表的尾部连上另一个链表头节点,再用冒泡排序:
ListNode* ListLink(ListNode **ppList_1,ListNode **ppList_2)
{
assert(ppList_1&&ppList_2);
ListNode *tail = *ppList_1;
while(tail->next != NULL)
{
tail = tail->next;
}
tail->next = *ppList_2;
ListBubb(ppList_1);
return *ppList_1;
}
但这种方法时间复杂太大,有没有更好的办法呢?
先找两个链表第一个节点的小的头链表,然后在这链表后面插两两比较小的节点。直至其中一个链表遇到NULL;
//链接链表并排序
ListNode* ListLink(ListNode **ppList_1,ListNode **ppList_2)
{
assert(ppList_1&&ppList_2);
ListNode *pList_1 = *ppList_1;
ListNode *pList_2 = *ppList_2;
if(pList_1->data > pList_2->data)//找到头节点小的链表
{
*ppList_1 = *ppList_2;
pList_2 = pList_2->next;
}
else
{
pList_1 = pList_1->next;
}
ListNode *pList = *ppList_1;
while(pList_1 && pList_2)
{
if(pList_1->data > pList_2->data)
{
pList->next = pList_2;
pList_2 = pList_2->next;
}
else
{
pList->next = pList_1;
pList_1 = pList_1->next;
}
pList = pList->next;
}
if(pList_1)//遇到NULL
{
pList = pList_2;
}
else
{
pList = pList_1;
}
return *ppList_1;
}