c语言实现单链表面试题(基础篇)
来源:互联网 发布:网络战略游戏 编辑:程序博客网 时间:2024/06/06 01:57
1.顺序便与单链表比较
顺序表:顺序表存储是将数据元素放到一块连续的内存储空间,相邻数据元素的存放地址也相邻,有动态存储和静态存储两种存储方式。
优点:(1)可以直接通过下标访问,支持随机访问,查找等效率较高。
(2)数据连续存放,空间利用率高,命中率高。
缺点:(1)当元素个数远小于预先分配的空间大小时,空间浪费比较严重;静态存储时,空间一经创建,大小不能改变,当需要存取的元素个数可能多于顺序表的元素个数时,会出现溢出问题。
(2)插入或删除数据效率较低,顺序表需要遍历移动元素。
链表:链表存储是程序运行过程中动态分配空间,相邻数据元素可任意存放,但所占存储空间分为两部分,一部分存放节点值,另一部分存放便是节点间关系的指针。
优点:(1)插入和删除效率较高,只需要改变指针指向即可。
(2)没有空间限制,只要存储器还有空间,就不会产生溢出问题。
缺点:(1)数据存放不连续,malloc开辟,空间碎片较多。
(2)查找速度较慢,当需要访问某个数据时,需要从第一个节点开始逐个查找。 适用场合:若线性表长度变化不大,且主要操作是查找很少插入删除时,可以采用顺序表;若线性表长度变化较大或者根本不知道多大,且其主要操作是插入删除很少查找时,可以采用链表,这样可以不用考虑存储空间大小问题。
//list.h
#include <stdio.h>#include <stdlib.h>#include <assert.h>#pragma oncetypedef int DataType;typedef struct ListNode{ DataType data; struct ListNode* next;}ListNode;
2.从尾到头打印单链表
void PrintTailToHead(ListNode* ppHead){ if (ppHead == NULL) { return; } PrintTailToHead(ppHead->next); printf("%d ", ppHead->data);}
3.删除一个无头单链表的非尾节点
void ErasenoTail(ListNode* pos){ ListNode* next; assert(pos&&pos->next); if (pos == -1) { return; } next = pos->next; pos->data = next->data; pos->next = next->next; free(next);}
4.在无头单链表的一个节点前插入一个节点
void InsertnoTail(ListNode* pos,DataType x){ assert(pos); if (pos == -1) { return; } ListNode* next= BuyNode(pos->data); next->next = pos->next; pos->next = next; pos->data = x;}
5.单链表实现约瑟夫环
ListNode* Joseph(ListNode* hus, size_t k){ ListNode* man,*next; assert(hus); man = hus; while (man->next != man) { size_t count = k; while (--count) { man = man->next; } next = man->next; man->data = next->data; man->next = next->next; free(next); } return man;}
6.逆置/反转单链表
void Reverse(ListNode** ppHead){ if (*ppHead == NULL) { return ; } else { ListNode* n0 = NULL, *n1 = *ppHead, *n2 = n1->next; while (n1) { n1->next = n0; n0 = n1; n1 = n2; if (n2) { n2 = n2->next; } } *ppHead = n0; }}
7.单链表排序(冒泡排序&快速排序)
void SortList(ListNode* pHead){ ListNode* tail = NULL; if (pHead==NULL&&pHead->next==NULL) { return; } while (tail!=pHead) { int exchange = 0; ListNode* cur = pHead, *next = cur->next; while (next != tail) { if (cur->data > next->data) { exchange = 1; DataType tmp = cur->data; cur->data = next->data; next->data = tmp; } cur = cur->next; next = next->next; } if (exchange == 0) { break; } tail = cur; }}
8.合并两个有序链表,合并后依然有序
ListNode* MergeList(ListNode* list1, ListNode* list2){ ListNode* list,*tail; if (list1 == NULL) return list2; if (list2 == NULL) return list1; if (list1->data < list2->data) { list = list1; list1 = list1->next; } else { list = list2; list2 = list->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; } if (list1 != NULL) { tail->next = list1; } else { tail->next = list2; } return list;}
9.查找单链表的中间节点,要求只能遍历一次链表
ListNode* FindMidNode(ListNode* pHead){ ListNode* slow = pHead; ListNode* fast = pHead; while (fast && fast->next&&fast->next->next) { slow = slow->next; fast = fast->next->next; } return slow;}
10.查找单链表的倒数第k个节点,要求只能遍历一次链表
ListNode* FindTailkNode(ListNode* pHead, size_t k){ ListNode* slow = pHead, *fast = pHead; while (--k) { if (fast == NULL) { return NULL; } fast = fast->next; } while (fast->next) { slow = slow->next; fast = fast->next; } return slow;}
//test.c
//Reverse/ErasenoTail/InsertnoTail/PrintTailToHeadvoid TestList1(){ ListNode* list = NULL; PushBack(&list, 0); PushBack(&list, 1); PushBack(&list, 2); PushBack(&list, 3); PushBack(&list, 4); PushBack(&list, 5); PrintList(list); PrintTailToHead(list); Reverse(&list); PrintList(list); ErasenoTail(Find(list,2)); PrintList(list); InsertnoTail(Find(list, 3),30); InsertnoTail(Find(list, 2),40); PrintList(list);}//Josephvoid TestList2(){ ListNode* tail; ListNode* list = NULL; PushBack(&list, 1); PushBack(&list, 2); PushBack(&list, 3); PushBack(&list, 4); PushBack(&list, 5); tail = Find(list, 5); tail->next = list; printf("live:%d\n", Joseph(list, 3)->data);}//SortListvoid TestList3(){ ListNode* list = NULL; PushBack(&list, 5); PushBack(&list, 3); PushBack(&list, 2); PushBack(&list, 7); PushBack(&list, 9); SortList(list); PrintList(list);}//MergeListvoid TestList4(){ ListNode* list; ListNode* list1 = NULL; ListNode* list2= NULL; PushBack(&list1, 1); PushBack(&list1, 3); PushBack(&list1, 5); PushBack(&list1, 7); PushBack(&list1, 9); PushBack(&list2, 0); PushBack(&list2, 2); PushBack(&list2, 4); PushBack(&list2, 6); PushBack(&list2, 8); list=MergeList(list1, list2); PrintList(list);}//FindMidNode/FindTailkNodevoid TestList5(){ ListNode* list1=NULL; PushBack(&list1, 0); PushBack(&list1, 1); PushBack(&list1, 3); PushBack(&list1, 5); PushBack(&list1, 7); PushBack(&list1, 9); SortList(list1); printf("mid:%d\n", FindMidNode(list1)->data); printf("tail k:%d\n", FindTailkNode(list1,3)->data);}#include test.hint main(){ TestList5(); system("pause"); return 0;}
“`
- C语言实现单链表面试题(基础篇)
- C语言实现单链表面试题(基础篇)
- c语言实现单链表面试题(基础篇)
- C语言实现单链表面试题--基础篇
- C语言实现单链表面试题--基础篇
- C语言实现单链表面试题--基础篇
- c语言实现单链表面试题--基础篇
- C语言实现单链表面试题_基础篇
- C语言实现单链表面试题---基础篇
- C语言实现单链表面试题 ----基础篇
- C语言实现单链表面试题(进阶篇)
- C语言实现单链表面试题——基础篇(上)
- C语言实现单链表面试题——基础篇(中)
- C语言实现单链表面试题——基础篇(下)
- c语言实现单链表面试题
- c语言实现单链表面试题之进阶篇
- C语言实现单链表面试题-------进阶篇
- 【C】单链表面试题(基础篇)
- CentOs6.8 hadoop集群搭建过程中的问题
- 上拉下拉加载数据的应用.....
- bzoj 5047: 空间传送装置 spfa
- 理解Angular中的$apply()以及$digest()
- Perl 入门实战:JVM 监控脚本(上)
- c语言实现单链表面试题(基础篇)
- python2.7学习笔记(-)
- bzoj1031 [JSOI2007]字符加密Cipher
- xjoi奋斗群群赛11
- 微信公众号开发接口权限与次数限制-微信开发教程13
- 欢迎使用CSDN-markdown编辑器
- bzoj5049 [Lydsy2017年5月月赛]导航系统
- JAVA文本框根据输入内容自动模糊查询(动态)
- 怎么看微信公众号开发文档-微信开发教程14