顺序表与链表各自的优缺点:
1. 顺序表支持随机访问,单链表不支持随机访问。
2. 顺序表插入 / 删除数据效率很低,时间复杂度为O(N)(除尾插尾删),单链表插入 / 删除效率更高,时间复杂度为O(1)。
3. 顺序表的CPU高速缓存效率更高,单链表CPU高速缓存效率低
1.倒着打印单链表
void PrintTailToHead(ListNode* pList)//倒着打印单链表
{
if (pList == NULL)
return;
PrintTailToHead(pList->_next);
printf("%d ", pList->_data);
}
2.删除无头单链表的非尾节点
void EraseNonTail(ListNode* pos)//删除无头单链表的非尾节点
{
assert(pos->_next&&pos);
ListNode* cur = pos->_next;
pos->_data = cur->_data;
pos->_next = cur->_next;
free(cur);
cur = NULL;
}
3.在无头单链表的一个非头节点前插入一个节点
void InsertNonHead(ListNode* pos,DataType x)//在无头单链表的一个非头节点前插入一个节点
{
assert(pos);
ListNode* cur = BuyNode(x);
ListNode* next = pos->_next;
DataType tmp = pos->_data;
pos->_data = cur->_data;
cur->_data = tmp;
cur->_next = pos->_next;
pos->_next = cur;
}
4.实现约瑟夫环,pList已经是循环链表
ListNode* JosephRing(ListNode* pList, int k)//约瑟夫环,pList已经是循环列表
{
if (pList == NULL)
{
return NULL;
}
ListNode* cur = pList;
while (cur->_next != cur)
{
int count = k;
while (--count)
{
cur = cur->_next;
}
ListNode* next = cur->_next;
cur->_data = next->_data;
cur->_next = next->_next;
free(next);
}
return cur;
}
5.单链表逆置
ListNode* Reserve(ListNode *pList) //单链表逆置
{
ListNode* newList = NULL;
ListNode* cur = pList;
while (cur)
{
//摘节点
ListNode* tmp = cur;
cur = cur->_next;
//头插
tmp->_next = newList;
newList = tmp;
}
return newList;
}
6.冒泡排序
void BubbleSort(ListNode* pList)//冒泡排序
{
//1.递归的方法
/*if (pList == NULL || pList->_next == NULL)
{
return;
}
ListNode* cur = pList;
while (cur->_next)
{
BubbleSort(cur->_next);
if (cur->_data > cur->_next->_data)
{
DataType tmp = cur->_data;
cur->_data = cur->_next->_data;
cur->_next->_data = tmp;
}
cur = cur->_next;
}*/
//2.一趟趟冒泡排序
if (pList == NULL || pList->_next == NULL)
{
return;
}
ListNode* tail = NULL;
while (tail != pList->_next)
{
int exchange = 0;
ListNode* cur = pList;
ListNode* next = cur->_next;
while (next != tail)
{
if (cur->_data > next->_data)
{
DataType tmp = cur->_data;
cur->_data = next->_data;
next->_data = tmp;
exchange = 1;
}
cur = cur->_next;
next = next->_next;
}
if (exchange == 0)
{
break;
}
tail = cur;
}
}
7.查找单链表的中间节点,要求只能遍历一次链表
ListNode* FindMidNode(ListNode* pList)//查找单链表的中间节点,要求只能遍历一次链表
{
if (pList == NULL || pList->_next == NULL)
{
return pList;
}
ListNode* slow = pList;
ListNode* fast = slow;
while (fast)
{
fast = fast->_next;
if (fast != NULL)
{
fast = fast->_next;
slow = slow->_next;
}
}
return slow;
}
8.查找倒数第K个节点,只遍历一个链表
ListNode* FindLastKNode(ListNode* pList,int k)//查找倒数第K个节点,只遍历一个链表
{
if (!pList || pList->_next == NULL)
{
return NULL;
}
ListNode* fast = pList;
ListNode* slow = fast;
while (k--)
{
if (!fast)
{
return NULL;
}
fast = fast->_next;
}
while (fast)
{
fast = fast->_next;
slow = slow->_next;
}
return slow;
}
9.合并两个有序的单链表,合并后依然有序
ListNode* MergeList(ListNode* pList1, ListNode* pList2)//合并两个有序的单链表,合并后依然有序
{
if (pList1 == NULL)
{
return pList2;
}
else if (pList2 == NULL)
{
return pList1;
}
ListNode* tmp = NULL;
if (pList1->_data < pList2->_data)
{
tmp = pList1;
pList1 = pList1->_next;
}
else
{
tmp = pList2;
pList2 = pList2->_next;
}
ListNode* newList = tmp;
while (pList1&&pList2)
{
if (pList1->_data < pList2->_data)
{
tmp->_next = pList1;
pList1 = pList1->_next;
}
else
{
tmp->_next = pList2;
pList2 = pList2->_next;
}
tmp = tmp->_next;
}
if (pList1)
{
tmp->_next = pList1;
}
if (pList2)
{
tmp->_next = pList2;
}
return newList;
}