数据结构
cany1000
码农。无所谓,像蜗牛一点一点爬。
展开
-
排序算法的稳定性
常见的排序算法的稳定性,每个都给出简单的理由。(1)冒泡排序冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改 变,所以冒泡排序是一种稳定排序算法。转载 2016-09-07 20:39:56 · 409 阅读 · 0 评论 -
链表中倒数第k个结点
题目描述输入一个链表,输出该链表中倒数第k个结点。/*struct ListNode { int val; struct ListNode *next; ListNode(int x):val(x), next(NULL) { }};*/class Solution { public: ListNode* FindKthToTail(Lis原创 2016-10-20 17:10:29 · 219 阅读 · 0 评论 -
快速排序
1、快速排序---- 快速排序(Quicksort)是对冒泡排序的一种改进,由C.A.R.Hoare在1962年提出。它的基本思想是:通过“一趟排序”将要排序的数据分割成独立的两部分,其中左部分的所有数据都比右部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。2、算法过程---- 设要排序的数组是A[0]原创 2017-01-02 16:34:06 · 295 阅读 · 0 评论 -
归并排序法
1、归并排序法(Merge Sort)--- 以下简称MS,是分治法思想运用的一个典范,其主要算法操作可以分为以下步骤:--1)将n个元素分成两个含n/2个元素的子序列--2)用MS将两个子序列递归排序(最后可以将整个原序列分解成n个子序列)--3)合并两个已排序好的序列MS的关键在于Merge过程。对于这一过程的理解,算法导论中给出了一个形象的模型。即假设桌面上有两堆已排好序原创 2017-01-05 10:30:37 · 454 阅读 · 0 评论 -
顺序查找和二分查找
1、顺序查找---- 又称线性查找,是从数组的第一个元素开始查找,直到找到待查找元素的位置。顺序查找适合于存储结构为顺序存储或链接存储的线性表。使用for循环等实现。int Find(int a[],int x){ int index = -1; for(int i=0;i<(sizeof(a)/sizeof(a[0]));i++) { if(a[i]==x) {原创 2017-01-02 15:15:27 · 3220 阅读 · 0 评论 -
插入排序法(一)
插入排序法: 假设前面所有的数都已排好序,将后面的数从后向前依次和已排好序的进行比较,直到出现比它小的,插在它的后面。代码如下:#include #include using namespace std;/* **** 插入排序 一直一个已排好序的序列,对新来的数,从后往前依次与排好序的数进行比较 直到找到比此数小的,然后插在它之后。*//原创 2016-03-22 13:48:05 · 338 阅读 · 0 评论 -
二叉树排序
1、二叉树排序--1)一个无序整数数组--2)创建二叉树,数组第一个元素为根结点,数组中下一个元素小于根的值放左边,大于的放右边。--3)中序遍历,结果即为数组从小到大的排序。2、代码实现#include using namespace std;#define dim(x) (sizeof(x)/sizeof(x[0]))void swap(int *x,int *y)原创 2017-01-03 16:05:57 · 1196 阅读 · 0 评论 -
双向冒泡排序
1、从两边同时进行冒泡排序一次排出一个最大值和最小值,n/2次,即while(left#include using namespace std;#define dim(x) (sizeof(x)/sizeof(x[0]))void swap(int *x,int *y){ int t = *x; *x = *y; *y = t;}//双向冒泡:从数组两端同时进行冒泡v原创 2017-01-02 14:00:26 · 1303 阅读 · 0 评论 -
简单选择排序算法
1、简单选择排序算法(Simple Selection Sort)---- 通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1#define MaxSize 10typedef struct { int r[MaxSize]; int length;}SqList;void swap(SqList *L,int i,int j){ int原创 2016-09-06 12:09:25 · 383 阅读 · 0 评论 -
折半查找法
1. 问题:假设现在有一个有序的数组array(已按升序排列好的),又有一个数num,现在查找这个数num是否在数组array中。问题分析:假设num在数组array中,那么怎么进行折半查找呢?1)先将num和数组中间的那个数比较2)如果num小于中间的那个数,那就继续在前一半进行查找3)如果num大于中间的那个数,就继续在后一半进行查找。4)如果查找到就返回num所在arr原创 2016-03-08 10:45:15 · 619 阅读 · 0 评论 -
直接插入排序
1、直接插入排序(Straight Insertion Sort)---- 直接插入排序的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。2、算法实现#define MaxSize 10 //要排序数组元素的最大值,可根据需要修改typedef struct { int r[MaxSize+1];//用于存储要排序数组,r[0]用作哨兵或临时原创 2016-09-06 14:59:04 · 399 阅读 · 0 评论 -
希尔排序
1、希尔排序是对直接插入排序进行改进后增加效率的排序算法。---- 直接插入排序的效率在某些时候是很高的,比如:--1)我们的记录本身就是基本有序的,只需要少量的插入操作,就可以完成整个记录集的排序工作。--2)记录数比较少的时候。思想:-- 如何将待排序的记录个数较少?将原本有大量记录数的记录进行分组,分割成若干个子序列,此时每个子序列待排序的记录个数就比较少了,然后在这原创 2016-09-07 14:07:13 · 280 阅读 · 0 评论 -
插入排序法(二)
前面已排好,从下标1开始比较。#include using namespace std;void InsertSort(int a[],int n){ int key,i = 1; while(i < n) { key = a[i]; int j = i-1; for(;j>=0;j--) { if(a[j] > key) { a[j+1] =原创 2016-04-03 16:57:22 · 284 阅读 · 0 评论 -
链表分割
题目描述编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以后保持原来的数据顺序不变。/*struct ListNode { int val; struct ListNode *next; ListNode(int x):va原创 2016-10-20 17:15:34 · 286 阅读 · 0 评论 -
折半插入排序
1、折半插入排序-定义---- 当直接插入排序进行到某一趟时,对于a[i]来讲,前边i-1个记录已经是有序的。此时可以不再用直接插入排序的方法,而改为先用折半查找法找出a[i]应插的位置,然后再插入。这种方法就是折半插入排序。2、算法思想---1)初始化:设定有序区为第一个元素,设定无序区为后面所有元素---2)依次取无序区的每个元素---3)通过二分法查找有序区,返回比这原创 2017-01-03 13:53:09 · 431 阅读 · 0 评论 -
求二进制数中1的个数
1、对于一个int型的变量,求其二进制表示中“1”的个数,要求算法的执行效率尽可能的高。算法一:---- 对整数除以2,余1的个数就是二进制表示中“1”的个数。#include using namespace std;int main(){ int number; cout<<"请输入一个整数:\n"; while(cin>>number) { int count原创 2016-10-24 14:20:28 · 568 阅读 · 0 评论 -
堆排序
1、堆排序---- 大顶堆---- 小顶堆2、算法实现#define MaxSize 10 //要排序数组元素的最大值,可根据需要修改typedef struct { int r[MaxSize+1];//用于存储要排序数组,r[0]用作哨兵或临时变量 int length; //用于记录顺序表的长度}SqList;void swap(SqList *L,int i,原创 2016-09-08 14:46:25 · 496 阅读 · 0 评论 -
排序-冒泡排序
1、排序---- 假设含有n个记录的序列为{r1,r2,....,rn},其相应的关键字分别为{k1,k2,....,kn},需确定一种排列,使其相应的关键字满足非递减/非递增的关系,即使得序列称为一个按关键字有序的序列,这样的操作就称为排序。2、排序的稳定性---- 假设ki=kj(1排序后ri仍然领先于rj,则称所用的排序方法是稳定的,反之,若可能使得排序后的序列中rj领先原创 2016-09-06 11:02:19 · 396 阅读 · 0 评论 -
链表结点的插入
---- 单链表第i个位置插入数据结点的算法思路:-- 1)声明一结点 p 指向链表头结点,初始化 j 从1开始;-- 2)当 j<i 时,就遍历链表,让 p 的指针向后移动,不断指向下一结点,j 累加1;-- 3)若到链表末尾p为空,则说明第 i 个元素不存在;-- 4)否则查找成功,在系统中生成一个空结点s;-- 5)将数据元素e赋值给s->data;-- 6)单链表的插入标准语句 s->next=p->next; p->next=s;-- 7)返回成功。原创 2016-05-01 16:33:51 · 716 阅读 · 0 评论 -
顺序表的操作
1、顺序表的追加,插入和删除---- 顺序表是把线性表中的所有元素按照其逻辑顺序,依次存储到指定存储位置开始的一块连续的存储区域中。特点:1)在顺序表中,各个元素的逻辑顺序跟物理顺序一致,第i项就存在第i个位置。2)对顺序表中的元素,既可以采用顺序访问,也可以采用随机访问。#include using namespace std;//LinearList#define原创 2016-12-22 16:53:13 · 438 阅读 · 0 评论 -
链表概述
1、数组是一种顺序存储的数据结构,逻辑上相邻的两个元素在物理上也是相邻的。 每个元素占用的内存相同,可以通过下标访问。 如果要增加或删除一个元素,需要移动大量元素。但可以快速访问数据。2、链表是一种链接(链式)存储的数据结构,逻辑上相邻的两个元素在物理上一般是不相邻的。 相邻元素之间的访问必须通过指针实现。 如果要访问链表中的一个元素,需要从第一原创 2016-05-01 09:30:39 · 457 阅读 · 0 评论 -
单链表的操作
1、单链表:线性链表插入:根据插入的位置,分3种,第一个结点前,最后一个结点后,插入在中间删除:也同样分为3种,删除第一个结点,删除最后一个结点,删除中间的结点#include using namespace std;typedef struct LinkNode{ int data; struct LinkNode *next;}LinkNode;//链表的创建Li原创 2016-12-22 19:42:48 · 268 阅读 · 0 评论 -
反转链表
将原链表逆序后输出。#include using namespace std;typedef struct NODE{ int data; NODE *next;}Node;//链表的创建Node *create(Node a[],int n){ Node *head = &a[0]; for(int i = 0;i < n-1;i++) { a[i].next原创 2016-04-11 15:18:57 · 1480 阅读 · 0 评论 -
红黑树
1、红黑树概念--- 红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:性质1. 节点是红色或黑色。性质2. 根节点是黑色。性质3 每个叶节点(NIL节点,空节点)是黑色的。性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)性质5. 从任一节原创 2017-01-05 10:44:21 · 203 阅读 · 0 评论 -
二叉树的遍历
1、定义---- 二叉树的遍历(traversing binary tree)是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。2、遍历算法---- 限定先左结点后右结点后,主要的遍历算法分为四种:--1)前序遍历(根结点--左子树--右子树)规则是若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。原创 2016-08-24 13:56:57 · 351 阅读 · 0 评论 -
二叉树的存储结构
---- 二叉树是非线性结构,其存储结构可以分为两种,即顺序存储结构和链式存储结构。1、顺序存储结构---- 二叉树的顺序存储,就是用一组连续的存储单元存放二叉树中的结点。即用一维数组存储二叉树中的结点。因此,必须把二叉树的所有结点安排成一个恰当的序列,结点在这个序列中的相互位置能反映出结点之间的逻辑关系。用编号的方法从树根起,自上层至下层,每层自左至右地给所有结点编号。---- 依据原创 2016-08-23 15:30:35 · 23398 阅读 · 1 评论 -
判断链表中是否有环/子串
怎么判断链表中是否有环?答:用两个指针来遍历这个单向链表,第一个指针p1,,每次走一步,第二个指针p2,每次走两步,当p2指针追上p1的时候,就表明链表当中有环路了。int testLinkRing(Link *head){ Link *t1 = head, *t2 = head; while(t1->next && t2->next) { t1 = t1-...原创 2018-05-28 15:33:23 · 380 阅读 · 0 评论 -
栈
1、栈(stack)是限定仅在表尾进行插入和删除操作的线性表。(表尾指栈顶)---- 把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。理解栈的定义需要注意:---- 首先它是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。只不过它是一种原创 2016-07-28 21:17:42 · 362 阅读 · 0 评论 -
图的存储结构-邻接矩阵和邻接表
1、邻接矩阵图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。设图G有n个顶点,则邻接矩阵是一个nxn的方阵,定义为:Arc[i][j]=1,若(vi,vj)∈E或∈E,反之等于0。如下图是一个简单无向图。我们可以设置两个数组,顶点数组为vertex[4]={v0,原创 2016-12-12 16:17:57 · 16577 阅读 · 0 评论 -
线性表习题二
1、已知 first 为单链表的表头指针,链表中存储的都是整型数据,试写出实现下列运算的递归算法:(1)求链表中的最大整数:(2)求链表的结点个数。(3)求链表中所有元素的平均值。#include using namespace std;typedef int Elemtype; typedef struct node{ Elemtype data; struct n原创 2016-07-28 16:56:40 · 3476 阅读 · 0 评论 -
顺序表
1、线性表--顺序表在计算机内部存储一张线性表(线性结构的数表),最为方便简单的就是用一组连续地址的内存单元来存储整张线性表。这种存储结构称为顺序存储结构,这种存储结构下的线性表就叫做顺序表。定义一张顺序表也就是在内存中开辟一段连续的存储空间,并给它一个名字进行标识。只有定义了一个顺序表,才能利用该顺序表存放数据元素,也才能对该顺序表进行各种操作。有两种定义顺序表的方法:一是静原创 2016-07-18 21:09:48 · 858 阅读 · 0 评论 -
线性表习题一
1、已知一个带表头结点的单链表,结点的结构为(data,link)。假设该链表只给出了表头指针list,在不改变链表的前提下请设计一个尽可能有效的算法,查找链表中倒数第k个位置上的结点(k为正数)。若查找成功,算法输出该结点的data域的值,并返回1,否则只返回0.要求:(1)描述该算法的基本设计思想;(2)描述该算法的详细实现步骤;(3)根据算法的基本设计思想和详细实现步骤,原创 2016-07-26 17:28:17 · 691 阅读 · 1 评论 -
产生随机数rand()
1、我们知道可以用srand()和rand()函数来产生随机数,但是这个具体怎么用呢,先看一个例子:int main(){ srand(1); int random; for(int i=0;i<10;i++) { random = rand()%5; cout<<random<<" "; } system("pause"); return 0;}输出:可以看出原创 2016-07-28 11:19:31 · 348 阅读 · 0 评论 -
单链表的整表创建
1、顺序存储结构的创建,其实就是一个数组的初始化,即声明一个固定类型和大小的数组并赋值的过程。而单链表和顺序存储结构就不一样,它不像顺序存储结构那么几种,它可以很散,是一种动态结构。对于每个链表来说,它所占用空间的大小和位置是不需要预先分配划定的,可以根据系统的情况和实际需求即时生成。所以创建单链表的过程就是一个动态生成链表的过程。即从“空表”的初始状态起,依次建立各元素结点,并逐个插翻译 2016-07-28 15:05:46 · 600 阅读 · 0 评论 -
链表结点的删除
---- 单链表第 i 个数据删除结点的算法思路:-- 1)声明结点 p和q,p指向链表第一个结点,初始化 j=1;-- 2)当 j<i 时,就遍历链表,让p指针向后移动,不断指向下一个结点,j 累加1;-- 3)若到链表末尾 p 为空,则说明第 i 个元素不存在;-- 4)否则查找成功,q=p->next;-- 5)单链表的删除标准语句:p->next=q->next;-- 6)将 q 结点中的数据赋值给e,作为返回。释放 q 结点。原创 2016-05-01 11:11:41 · 863 阅读 · 0 评论 -
单链表结构和顺序存储结构
1、对单链表结构和顺序存储结构做对比---- 1)存储分配方式-- 顺序存储结构用一段连续的存储单元依次存储线性表的数据元素。-- 单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素。---- 2)时间性能-- 查找:顺序存储结构O(1),单链表O(n)-- 插入和删除:========== 顺序存储结构需要平均移动表长一半的元素,时间为O(n)。===原创 2016-07-21 10:56:35 · 3342 阅读 · 0 评论 -
数据结构基本概念
1、数据(Data)---- 是对信息的一种符号表示。在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。2、数据元素(Data Element)---- 是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。一个数据元素可由若干个数据项组成。数据项是数据的不可分割的最小单位。3、数据对象(Data Object)---- 是性质相同的数据元素的原创 2016-07-21 21:11:49 · 422 阅读 · 0 评论 -
线性表
1、线性表的定义---- 通常,定义线性表为n(n>=0)个数据元素(或称为表元)的有限序列。记为L=(a1,a2,...,an). 其中L是表名,ai是表中的结点,是不可再分割的数据。n是表中表元的个数,也称为表的长度,若n=0叫做空表。---- 在非空的数据元素集合中,线性表的特点是:--- 1)存在唯一的一个称作“第一个”的元素。--- 2)存在唯一的一个称作“最后一翻译 2016-07-24 18:20:59 · 865 阅读 · 0 评论 -
链表排序
将一个链表中的元素按照从小到大的顺序进行排序#include #include using namespace std;//定义结构体类型Ptypedef struct point{ int data; struct point *next;//指向结构体的指针}P;//创建链表(指定长度,存在结构体数组中),返回头指针P *createlink(P a[],int n)原创 2016-01-22 13:43:51 · 444 阅读 · 0 评论 -
链表结点移动
将已知链表中元素值最小的结点移到第一个结点,来看代码:#include "stdafx.h"#include #include using namespace std;//定义结构体类型Ptypedef struct point{ int data; struct point *next;//指向结构体的指针}P;//创建链表(指定长度,存在结构体数组中),返回头指针P原创 2016-01-16 19:04:13 · 4124 阅读 · 0 评论