1.比较顺序表和链表的优缺点,说说它们分别在什么场景下使用?
顺序表:内存中地址连续,长度不可变更,支持随机查找 可以在O(1)内查找元素
适用于需要大量访问元素的 而少量增添/删除元素的程序
链表:内存中地址非连续,长度可以实时变化,不支持随机查找 查找元素时间复杂度O(n)
适用于需要进行大量增添/删除元素操作 而对访问元素无要求的程序
顺序表的CPU高速缓存效率更高,单链表CPU高速缓存效率低.
程序源代码
2 从尾到头打印单链表 (用递归实现)
void PrintfTailtoHead(ListNode* pList)//递归
{
if (pList == NULL)
return;
PrintfTailtoHead(pList->next);
printf("%d->", pList->data);
}
3.删除一个无头单链表的非尾节点
void EraseNonTail(ListNode* pos)//删除pos后面的结点
{
assert(pos);
assert(pos->next);
ListNode* next = pos->next;
pos->next = next->next;
free(next);
}
4.在无头单链表的一个节点前插入一个节点
void InsertNonHead(ListNode* pos,DataType x)//在pos前插入一个结点tmp
{
ListNode* tmp = BuyNode(x);
ListNode* next = pos->next;
pos->next = tmp;
tmp->next = next;
DataType tmpdata = pos->data;
pos->data = tmp->data;
tmp->data = tmpdata;
}
5.单链表实现约瑟夫环
ListNode* JosePhRing(ListNode* list, int k)
{
if (list == NULL)
return NULL;
ListNode* cur = list;
while (cur != cur->next)
{
int count = k;
while (--count)
{
cur = cur->next;
}
ListNode* next = cur->next;
cur->data = next->data;
cur->next = next->next;
free(next);
}
return cur;
}
6.逆置/反转单链表
ListNode* Reverse(ListNode* list)
{
ListNode* newlist = NULL;
ListNode* cur = list;
while (cur)//头插法
{
ListNode* tmp = cur;
cur = cur->next;
tmp->next = newlist;
newlist = tmp;
}
return newlist;
}
7.单链表排序(冒泡排序&快速排序)
void BubbleSort(ListNode* list)
{
if (list == NULL || list->next == NULL)
{
return;
}
ListNode* tail = NULL;
while (tail != list->next)
{
ListNode* cur = list;
ListNode* next = cur->next;
while (next != tail)
{
if (cur->data > next->data)
{
DataType data = cur->data;
cur->data = next->data;
next->data = data;
}
cur = cur->next;
next = next->next;
}
tail = cur;
}
}
8.合并两个有序链表,合并后依然有序
ListNode* Merge(ListNode* list1, ListNode* list2)
{
ListNode* list = NULL;
//取两个链表中最小的数做头结点
if (list1->data < list2->data)
{
list = list1;
list1 = list1->next;
}
else
{
list = list2;
list2 = list2->next;
}
ListNode* 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;
}
if (list1)
tail->next = list1;
if (list2)
tail->next = list2;
return list;
}
9.查找单链表的中间节点,要求只能遍历一次链表
ListNode* FindMidNode(ListNode* list)
{
ListNode* slow = list,*fast = list;
while (fast&&fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
10.查找单链表的倒数第k个节点,要求只能遍历一次链表
ListNode* FindTailkNode(ListNode* list, int k)
{
ListNode *slow = list,*fast = list;
while (k--)
{
if (fast == NULL)
return NULL;
fast = fast->next;
}
while (fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
测试2 3 5 6
void Test3()
{
ListNode* list = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
PrintfTailtoHead(list);
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
ListNode* pos = Find(list, 2);
EraseNonTail(pos);
PushBack(&list, 1);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
pos = Find(list, 3);
InsertNonHead(pos, 2);
PrintList(list);
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
ListNode* newlist=Reverse(list);
PrintList(newlist);
}
int main()
{
Test3();
system("pause");
return 0;
}
测试4
void test4()
{
ListNode* list = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PushBack(&list, 5);
ListNode* pos = Find(list, 5);
pos->next = list;
ListNode* last = JosephRing(list, 3);
printf("幸存者:%d\n", last->data);
}
int main()
{
//test7();
//test6();
test4();
//test8();
system("pause");
return 0;
}
测试7void test5()
{
ListNode* list = NULL;
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 1);
PushBack(&list, 4);
PushBack(&list, 6);
PushBack(&list, 5);
PrintList(list);
BubbleSort(list);
PrintList(list);
}
int main()
{
test5();
system("pause");
return 0;
}
测试8void test6()
{
ListNode* list1 = NULL;
PushBack(&list1, 1);
PushBack(&list1, 2);
PushBack(&list1, 4);
PushBack(&list1, 6);
PushBack(&list1, 8);
PrintList(list1);
ListNode* list2 = NULL;
PushBack(&list2, 2);
PushBack(&list2, 3);
PushBack(&list2, 5);
PushBack(&list2, 6);
PrintList(list2);
ListNode* list = Merge(list1, list2);
PrintList(list);
}
int main()
{
//test7();
test6();
//test4();
system("pause");
return 0;
}
测试9
void test7()
{
ListNode* list = NULL;
PushBack(&list, 1);
PushBack(&list, 3);
PushBack(&list, 5);
PushBack(&list, 7);
PushBack(&list, 9);
ListNode* mid= FindMidNode(list);
printf("%d\n", mid->data);
}
int main()
{
test7();
//test6();
//test4();
system("pause");
return 0;
}
测试10void test8()
{
ListNode* list = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PushBack(&list, 5);
ListNode* ret = FindTailkNode(list,3);
printf("%d\n", ret->data);
}
int main()
{
//test7();
//test6();
//test4();
test8();
system("pause");
return 0;
}