# 基础链表题

1.总结顺序表和链表的优缺点，说说它们分别在什么场景下使用？

2.从头到尾打印单链表

void Start_to_End(ListNode *pList)
{
ListNode *cur = pList;
if (pList == NULL)
{
return;
}
Start_to_End(cur->next);//访问到最后一个元素时停止
printf("%d ", cur->data);
}

3.删除一个无头单链表的非尾节点

1>,记录下pos的下一个节点；
2>,将pos下一个节点prev的数据赋给pos节点；
3>,让pos的下一个节点指向prev的下一个节点；
4>,最后free掉prev即可。

void Delete_NonHead(ListNode *pos)
{
assert(pos&&pos->next);
ListNode *prev = pos->next;
pos->data = prev->data;
pos->next = prev->next;
free(prev);
}

4.在无头单链表的一个非头节点前插入一个节点

2>,在pos节点的后面建立一个新的节点，改变指针的指向关系；
3>,建立一个临时变量，将pos的data和新建节点的data交换；

void Insert_Front_Node(ListNode *pos, DataType x)
{
assert(pos);
ListNode *prev = NewListNode(x);
ListNode *next = pos->next;
pos->next = prev;
prev->next = next;
int tmp = pos->data;
pos->data = prev->data;
prev->data = tmp;
}

2>,在pos节点的后面创建新节点，data为pos的data，将pos的data置为要插入新建节点的data；
3>, 改变指针的指向关系。

void Insert_Front_Node(ListNode *pos, DataType x)
{
assert(pos);
ListNode *next = pos->next;
ListNode *prev = NewListNode(pos->data);
pos->data = x;
pos->next = prev;
prev->next = next;
}

5.单链表实现约瑟夫环

ListNode* Joseph(ListNode *hum, size_t k)
{
assert(hum);
ListNode *man = hum;
while (man->next == man)
{
while (--k)
{
man = man->next;
}
ListNode *next = man->next;
man->data = next->data;
man->next = next->next;
free(next);
}
return man;
}

6.逆置/反转单链表

ListNode* Reverse_List(ListNode **ppList)
{
ListNode *start = *ppList;
ListNode *newlist = NULL;
while (start)
{
ListNode *cur = start->next;
start->next = newlist;
newlist = start;
start = cur;
*ppList = newlist;
}
return newlist;
}

7.单链表排序—–冒泡排序

void Bubble(ListNode *pList)
{
ListNode* tail = NULL;
if (pList == NULL || pList->next == NULL)
{
return;
}
while (tail != pList->next)
{
int flag = 0;
ListNode *start = pList;
ListNode *next = start->next;
while (next != tail)
{
if (start->data > next->data)
{
flag = 1;
DataType ret = start->data;
start->data = next->data;
next->data = ret;
}
start = start->next;
next = next->next;
}
if (flag == 0)
{
break;
}
tail = start;
}
}

8.合并两个有序链表, 合并后依然有序
1>,当list1为NULL时，返回list2;当list2为NULL时，返回list2;
2>,都不为空时，依次进行比较，如果节点的值小，就将该节点链到list上并指向下一个节点，data大的节点不变，遇到相等data时，任选一个节点链到list上；
3>,当有链表为空后，将另一个链表的值直接链到list上，返回list。

ListNode* Merge_list(ListNode* List1, ListNode* List2)
{
if (List1 == NULL)
{
return List2;
}
if (List2 == NULL)
{
return List1;
}
ListNode* List = NULL;
ListNode* tail = NULL;
if (List1->data < List2->data)
{
List = List1;
List1 = List1->next;
}
else if (List1->data>List2->data)
{
List = List2;
List2 = List2->next;
}
tail = List;
while (List1&&List2)
{
if (List1->data <= List2->data)
{
tail->next = List1;
List1 = List1->next;
}
else
{
tail->next = List2;
List2 = List2->next;
}
tail = tail->next;   //用tail遍历
if (List1 == NULL)
{
tail->next = List2;
}
else if (List2 == NULL)
{
tail->next = List1;
}
}
return List;
}

9.查找单链表的中间节点，要求只能遍历一次链表

ListNode* Find_MidHead(ListNode* pList)
{
ListNode* slow = pList;
ListNode* fast = pList;
while (fast && fast->next && fast->next->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}

10.查找单链表的倒数第k个节点，要求只能遍历一次链表

ListNode* Find_KHead(ListNode* pList, size_t k)
{
ListNode* slow = pList;
ListNode* fast = pList;
while (--k)
{
if (fast == NULL)
{
return NULL;
}
else
{
fast = fast->next;
}
}
while (fast->next)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}

• 评论

• 上一篇
• 下一篇