数据结构与算法
满城丶琉璃月
一蓑烟雨,满城风絮...
展开
-
用双向循环链表实现凯撒(Caesar)密码
凯撒密码简介:它是一种代换密码。据说凯撒是率先使用加密函的古代将领之一,因此这种加密方法被称为凯撒密码。凯撒密码作为一种最为古老的对称加密体制,在古罗马的时候都已经很流行,他的基本思想是:通过把字母移动一定的位数来实现加密和解密。明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推X将变成A,Y变成...原创 2018-05-10 23:52:00 · 1055 阅读 · 0 评论 -
实现单链表反转——递归版本和迭代版本
首先,关于递归的知识,可以参考我的这篇 递归:汉诺塔 关于单链表的知识可以参考我的这篇 单链表整表创建的两种方法(头插法和尾插法)本文中链表的结构定义如下:typedef struct Node{ int data; Node *next;} Node, *List;想要反转整个链表,可以考虑一个一个的结点从后往前反转,这就考虑到了递归与回溯,所以可以用递归实现...原创 2019-03-18 11:41:16 · 1311 阅读 · 0 评论 -
七大排序算法之简单算法系列(一)——冒泡排序
冒泡排序(Bubble Sort)是一种交换排序冒泡排序的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。可以把冒泡排序理解为一种改进的交换排序算法。那么,就先从交换排序算法说起吧。其实,谈到排序算法,我们脑海中自然而然最容易想到的算法应该就是交换排序算法了。也就是利用两层循环内层循环探测到的元素与外层那个元素逐一比较,如果小就进行交换,这样每一趟就能...原创 2019-03-12 11:42:37 · 181 阅读 · 0 评论 -
反转字符串——递归版本和非递归版本
题目的要求就是输入一个字符串,然后输出它的逆序。递归版本:需要真正理解递归的精髓:压栈和出栈#include<stdio.h>#include<string.h>void reverse(char* str){ char tmp = *str;//用tmp存入 字符串的第一个字符 int len = strlen(str);//求当前字符串的长度 ...原创 2019-03-18 11:41:24 · 289 阅读 · 0 评论 -
七大排序算法之简单算法系列(二)——简单选择排序
简单选择排序(Simple Selection Sort)原理:通过n-1次关键字之间的比较,从n-i+1个记录中找到关键字最小的记录,并和第i个记录交换。在冒泡排序中,我们每次都做了交换,而这里我们不需要每次都进行交换,而是把最小的数和第i个记录交换。直接看代码进行理解。简单选择排序的代码实现:#include <iostream>using namespa...原创 2019-03-12 12:30:46 · 357 阅读 · 0 评论 -
七大排序算法之简单算法系列(三)——直接插入排序
直接插入排序(Straight Insertion Sort)直接插入排序的基本操作:将一个记录插入到已经排好序的有序表中,从而得到一个新的。记录数增1的有序表。直接插入排序理解和实现起来都比较简单,又称为简单插入排序。方法就是,将待排的序列(无序表)中的元素一个个抽出,再逐个插入到已经排好的序列中(有序表)。C++代码实现如下:#include <iostream&g...原创 2019-03-12 15:12:09 · 170 阅读 · 0 评论 -
七大排序算法之改进算法系列(四)——希尔排序
希尔排序(Shell Sort)希尔排序是由D.L.Shell于1959年提出来的一种排序算法。需要指出的是,在这之前排序算法的时间复杂度基本上都是O(n²)的,希尔排序算法是突破这个时间复杂度的第一批算法之一。回想一下直接插入排序过程,排序过程中,我们可以设置一条线,左边是排好序的,右边则是一个一个等待排序,如果最小的那个值在最右边,那么排这个最小值的时候,需要将所有元素向右边移动一位。...原创 2019-03-12 17:05:48 · 337 阅读 · 0 评论 -
七大排序算法之总结篇
七大排序算法指的是:冒泡排序、简单选择排序、直接插入排序、希尔排序、堆排序、归并排序、快速排序关于这些排序算法的具体介绍和实现方法可参考下面这些链接:七大排序算法之简单算法系列(一)——冒泡排序七大排序算法之简单算法系列(二)——简单选择排序七大排序算法之简单算法系列(三)——直接插入排序七大排序算法之改进算法系列(四)——希尔排序七大排序算法之改进算法系列(五)——堆排序...原创 2019-03-18 11:34:58 · 157 阅读 · 0 评论 -
七大排序算法之改进算法系列(五)——堆排序
堆排序(Heap Sort):就是利用堆(假设利用大顶堆)进行排序的方法。堆排序可以看成是简单选择排序的一种升级版本。为了弄清楚堆排序,首先来学习几个概念,分别是堆、大顶堆、小顶堆堆是具有下列性质的完全二叉树:每个节点的值都大于或者等于其左右孩子节点的值,称为大顶堆;或者每个节点的值都小于或者等于其左右孩子节点的值,称为小顶堆可见,根结点一定是堆中所有结点最大或者最小者,如果按...原创 2019-03-14 21:50:19 · 666 阅读 · 0 评论 -
七大排序算法之改进算法系列(七)——快速排序
快速排序(Quick Sort):快速排序的原理:参考这篇 快速排序(过程图解)快速排序的代码实现:#include <iostream>using namespace std;void swap(int k[], int low, int high){ int temp; temp = k[low]; k[low] = k[high]; k[high...原创 2019-03-18 11:18:30 · 440 阅读 · 0 评论 -
七大排序算法之改进算法系列(六)——归并排序
归并排序(Merging Sort):归并排序是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。实际上就是将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归方法将排好序的半子表合并成越来越大的有序...原创 2019-03-17 19:22:26 · 414 阅读 · 0 评论 -
单链表整表创建的两种方法(头插法和尾插法)
线性表可分为顺序存储结构和链式存储结构顺序存储结构的创建,其实就是一个数组的初始化,即声明一个类型和大小的数组并赋值的过程。而单链表和顺序存储结构就不一样,它的每个数据的存储位置不需要像数组那样集中,它可以很散,是一种动态结构。对于每个链表来说,它所占用的空间大小和位置并不需要预先分配划定,可以根据系统的情况和实际的需求即时生成。所以,创建单链表的过程就是一个动态生成链表的过程。即从“空表”的...原创 2018-05-06 15:53:34 · 31791 阅读 · 4 评论 -
递归:汉诺塔
一、递归的思想递归分为递推和回归两个过程 以求一个数n的n!为例: 递推:若路人A能帮我把(n-1)!求出来,那我只需要在此基础上乘n就行了路人A会想,若路人B能帮我把(n-2)!求出来,那我只需要在此基础上乘(n-1)就行了。 照这样执行下去,总有一个人的工作是只需要把1!求出来就行了,那这个非常简单,我们定义一下1!=1就可以了。 回归:当有人把1!=1算出来之后,就要开始...原创 2018-03-28 22:06:30 · 247 阅读 · 0 评论 -
链表创建函数:形参用一级指针和用二级指针的区别
之前写一个链表创建的函数,在用typedef对结构体进行取别名的时候,了解到typedef关键字可以为一个结构体取两个别名,于是自己就尝试了一下///使用typedef定义结构体时可以为其起两个别名typedef struct List //定义结构体{ int num; struct List *next;}Node,*LinkList; //Node相当于结构体struct...原创 2018-05-15 16:35:40 · 1107 阅读 · 3 评论 -
腾讯面试题:快速找到未知长度单链表的中间结点
题目:快速找到未知长度单链表的中间结点首先分析一下,既然是一个面试题,就一定有普通方法和高级方法,而高级方法无疑会为你大大加分!普通方法很简单:首先遍历一遍单链表以确定单链表的长度L。然后再此从头结点出发循环L/2次找到单链表的中间结点。普通方法的算法复杂度为:O(L+L/2) = O(3L/2)普通方法的实现代码: #include<stdio.h> #include&...原创 2018-05-07 10:04:25 · 1152 阅读 · 0 评论 -
循环链表解决约瑟夫问题
约瑟夫问题:据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越...原创 2018-05-08 10:44:33 · 6115 阅读 · 1 评论 -
魔术师发牌问题
魔术师发牌问题的简介:一位魔术师掏出一叠扑克牌,魔术师取出其中13张黑桃,洗好后,把牌面朝下。说:“我不看牌,只数一数就能知道每张牌是什么?”魔术师口中念一,将第一张牌翻过来看正好是A;魔术师将黑桃A放到桌上,继续数手里的余牌,第二次数1,2,将第一张牌放到这叠牌的下面,将第二张牌翻开,正好是黑桃2,也把它放在桌子上。第三次数1,2,3,前面二张牌放到这叠牌的下面,取出第三张牌,正好是黑桃3,这样...原创 2018-05-08 17:12:26 · 360 阅读 · 0 评论 -
利用栈的LIFO特点将二进制数转换为十进制数
栈的LIFO特点:我们知道“栈”这种数据结构具有后进先出(LIFO)的特点,也就是最后入栈的数据最先被弹出。那这跟进制转换有什么关系呢?进制转换原理:假如我们从键盘输入一个二进制数1101,先看人工是如何转换成十进制的?我们只需要将二进制不同位上的数乘上它相应的权值即可,也就是1*2^0+0*2^1+1*2^2+1*2^3=13。也就是最后被输入的数字权值最低。所以用计算机模拟的话,就是利用栈的L...原创 2018-05-15 15:33:41 · 571 阅读 · 0 评论 -
树结构的双亲孩子表示法
以如下形式的树结构为例:该树的深度为3, 其双亲孩子表示法如下:表中第一列为结点编号,第二列为结点数据,第三列为该节点的双亲编号(根节点双亲为-1),后面的单链表表示了该节点所有的孩子,从左至右依次进行遍历。 代码实现如下:#define MAX_TREE_SIZE 100typedef char ElemType;// 孩子结点typedef struc...原创 2019-02-25 11:05:58 · 3251 阅读 · 0 评论 -
建立一棵二叉树
首先,要想建立一棵二叉树就要知道二叉树的三种遍历方法:前序遍历,中序遍历和后序遍历。不知道的可自行查阅。为了方便二叉树的表示,我们首先对二叉树进行扩展,将仅有空指针的结点变成虚节点,引入左右孩子(用^或#等符号表示),我们称这种变形后的二叉树为扩展二叉树。原二叉树扩展二叉树有了扩展二叉树,按照前序遍历的方法,上述树可写成AB#D##C##外面代码实现了二叉树的建立和前序...原创 2019-02-26 09:19:56 · 2766 阅读 · 1 评论 -
马踏棋盘问题(骑士周游问题、跳马问题、哈密尔顿通路问题)
马踏棋盘问题描述:在国际象棋中,象棋盘由如下所示8*8的64个方格组成,将国际象棋中的一个马放在棋盘中的任意一个位置(马的走法如下图所示),问马是否可以用63步走遍棋盘的所有位置?哈密尔顿路径:图G中的哈密尔顿路径指的是经过图G中每个顶点,且只经过一次的一条轨迹。如果这条轨迹是一条闭合的路径(从起点出发不重复地遍历所有点后仍能回到起始点),那么这条路径称为哈密尔顿回路。实现这一...原创 2019-02-26 23:22:09 · 1781 阅读 · 0 评论