有书共读《算法与数据结构题目最优解》(在线编程题总结2)
Posted 软件开发者社区
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有书共读《算法与数据结构题目最优解》(在线编程题总结2)相关的知识,希望对你有一定的参考价值。
书籍:《算法与数据结构题目最优解》
该书第二章——《链表问题》,总结我已放在CSDN中,详见:
。
1、线性表的简介
线性表是一种线性结构,它是由零个或多个数据元素构成的有限序列。线性表的特征是在一个序列中,除了头尾元素,每个元素都有且只有一个直接前驱,有且只有一个直接后继,而序列头元素没有直接前驱,序列尾元素没有直接后继。数据结构中常见的线性结构有数组、单链表、双链表、循环链表等。线性表中的元素为某种相同的抽象数据类型。可以是C语言的内置类型或结构体,也可以是C++自定义类型。
2、数组
数组在实际的物理内存上也是连续存储的,数组有上界和下界。C语言中定义一个数组:数组下标是从0开始的,a[0]对应第一个元素。其中,a[0]称为数组a的下界,a[n]称为数组a的上界。超过这个范围的下标使用数组,将造成数组越界错误。数组的特点是:数据连续,支持快速随机访问。数组分为固定数组与动态数组。其中固定数组的大小必须在编译时就能够确认,动态数组允许在运行时申请数组内存。复杂点的数组是多维数组,多维数组实际上也是通过一维数组来实现的。在C语言中,可以通过malloc来分配动态数组,C++使用new。另外,C++的标准模板库提供了动态数组类型vector以及内置有固定数组类型array。
3、链表的分类(有篇博客总结得很全面
)
(1)单向链表
(2)单向循环链表
(3)双向链表
(4)双向循环链表
4、单向链表
单向链表是链表的一种。链表由节点所构成,节点内含一个指向下一个节点的指针,节点依次链接成为链表。因此,链表这种数据结构通常在物理内存上是不连续的。链表的通常含有一个头节点,头节点不存放实际的值,它含有一个指针,指向存放元素的第一个节点。
5、单向循环链表
单向循环链表是另一种形式的链式存储结构,其特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。由此,从表中的任一结点出发均可找到表中的其他结点。
6、双向链表
以上讨论的链式存储结构的特点只有一个指示直接后继的指针域,由此,从某个结点出发只能顺着指针往后寻找其他结点。若要寻找结点的直接的前驱,则需从表头指针出发。换句话说,在单链表中,NextElem的执行时间为O(1),而PriorElem的执行时间为O(n)。为克服单链表这种单向性的缺点,可利用双向链表。
双向链表的每个结点除含有数据域外,还有两个指针域,分别指向直接前驱结点和直接后继结点。因此,从双向链表中的任一结点开始,均可方便地访问其前驱结点和后继结点。具体见博客:
7、双向循环链表
和单向链表相比,多了一个前驱结点。如果他为空,那么next和prior都指向自己。而对于双循环链表,只需要最后一个元素的next指向head->next,head->next的prior指向最后一个节点即可。具体见博客:
8、实例分析
若使用标准库,需添加#include <list>,下面是常见一些操作:
assign() 给list赋值 back() 返回最后一个元素 begin() 返回指向第一个元素的迭代器 clear() 删除所有元素 empty() 如果list是空的则返回true end() 返回末尾的迭代器 erase() 删除一个元素 front() 返回第一个元素 get_allocator() 返回list的配置器 insert() 插入一个元素到list中 max_size() 返回list能容纳的最大元素数量 merge() 合并两个list pop_back() 删除最后一个元素 pop_front() 删除第一个元素 push_back() 在list的末尾添加一个元素 push_front() 在list的头部添加一个元素 rbegin() 返回指向第一个元素的逆向迭代器 remove() 从list删除元素 remove_if() 按指定条件删除元素 rend() 指向list末尾的逆向迭代器 resize() 改变list的大小 reverse() 把list的元素倒转 size() 返回list中的元素个数 sort() 给list排序 splice() 合并两个list swap() 交换两个list unique() 删除list中重复的元素
(1)表的基本操作
#include <list> #include <iostream> using namespace std; int main(){ //list<int> L1{4,2,6,5}; list<int> L1; list <int>::iterator L1_iter; L1.push_back(4); L1.push_back(2); L1.push_back(6); L1.push_back(5); L1.reverse();//反转 for (L1_iter = L1.begin(); L1_iter != L1.end();L1_iter++){ cout << " " << *L1_iter; } cout << endl; system("pause"); return 0; }
(2)剑指offer面试题24——
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* ReverseList(ListNode* pHead) { ListNode* pReverseHead = nullptr; ListNode* pNode = pHead; ListNode* pPrev = nullptr; while(pNode!=nullptr){//输入的链表不为空 ListNode* pNext = pNode->next; if(pNext == nullptr)//只有一个节点 pReverseHead = pNode; //存在多个节点时,交换 pNode->next = pPrev; pPrev = pNode; pNode = pNext; } return pReverseHead; } };
以上是关于有书共读《算法与数据结构题目最优解》(在线编程题总结2)的主要内容,如果未能解决你的问题,请参考以下文章
程序员代码面试指南 IT名企算法与数据结构题目最优解 ,左程云著pdf高清版免费下载