进阶
Persistence_Y_1
这个作者很懒,什么都没留下…
展开
-
C++函数重载, 缺省参数
在我们的自然语言当中, 一个词在不同的情景之下可能会有多重不同的含义, 但是我们可以通过合理地判断来确定该词的真正含义, 这种情况, 我们可以说该词被"重载"了.关于函数重载的概念函数重载其实就是函数的一种特殊的情况, 在我们的C++中允许在同一作用域当中声明几个功能类似的同名函数, 但是这个同名函数的形参列表(参数个数或是参数类型或是参数的顺序)必须不同, 经常用来处理想要实现功能类似而数据...原创 2019-09-26 10:40:21 · 272 阅读 · 0 评论 -
通过前序遍历的数组"ABD##GI##J###CE#HK###F##"构建二叉树
头文件 BTree.h#ifndef _BTREE_H#define _BTREE_Htypedef char BTDataType;typedef struct BinaryTreeNode{ BTDataType data; struct BinaryTreeNode* lchild; struct BinaryTreeNode* rchild;}BTNode;//通过...原创 2019-08-25 17:08:38 · 511 阅读 · 0 评论 -
单链表相关的两道题目(判断是否链表是否成环, 完成单链表逆置)
对无头单向非循环链表的回顾在此基础上来看几道关于单链表的题目1.判断链表是否成环先看这样一个图两条平行线如果让A和B分别从一条线的起点出发,最终必然不会相遇再看另一种情况这时如果A和B都从起点O出发,A的速度为v,B的速度为2v,最终两人一定会相遇,这其实就对应了在单链表中出现环的情况.也就是说为了判断链表中是否形成环,我们需要两个指针一开始都指向头(plist->_he...原创 2019-08-15 18:10:59 · 200 阅读 · 0 评论 -
判断两个单链表是否相交,相交则返回两个链表相交的结点
判断两个链表是否相交,相交则返回两个链表相交的结点为了让判断两个链表是否相交,我们首先要做的就是将两个链表进行"对齐".(两个链表相交也就是说,从相交的结点开始,后面两个链表内容相同).所以我们的思路就是首先通过链表遍历,求出两个链表的长度,得到其差值.创建两个指针分别指向这两个链表的头位置.然后对较长的链表开始从头遍历差值部分.接下来让两个指针一起向前走,直至相遇则得到两链表相交结点,...原创 2019-08-24 17:17:53 · 304 阅读 · 0 评论 -
常见排序及算法实现(二)希尔排序
希尔排序又称缩小增量排序,是对插入排序的优化.举例来说明希尔排序:假设初始数据为9 1 2 5 7 4 8 6 3 5 共10个数据取 gap = n / 2 即 gap = 10 / 2 = 5现在来看第一趟排序具体的分组我们可以这样去看,数组中的数据下标为0 - 9.gap = 5.将原数据分为5组数据.这也就是说下标0与下标0 + 5一组,即上图中的9 与 4, 9 &g...原创 2019-09-12 20:50:09 · 191 阅读 · 0 评论 -
常见排序及算法实现(一)插入排序
#include <stdio.h>#include <stdlib.h>#define BUFSIZE 10000void InsertSort(int* src, int n){ int i, j; int tmp; for (i = 1; i < n; ++i){ tmp = src[i]; for (j = i; j > 0 &a...原创 2019-09-08 21:06:01 · 138 阅读 · 0 评论 -
对带头双向循环链表增删操作的回顾
头文件List.h存放函数声明#ifndef _LIST_H#define _LIST_H#include <stdio.h>#include <stdlib.h>#include <assert.h>typedef int LTDataType;typedef struct ListNode{ LTDataType _data; str...原创 2019-08-10 14:35:59 · 68 阅读 · 0 评论 -
对无头单向非循环链表的回顾
首先创建一个头文件存放所需要的函数功能的声明slist.h#ifndef _SLIST_H#define _SLIST_H#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <malloc.h>typedef int SLTDataType;typede...原创 2019-08-07 17:04:55 · 107 阅读 · 0 评论 -
环形队列的实现
头文件dequeue.h存放函数声明,声明结构体#ifndef _DEQUEUE_H#define _DEQUEUE_H#include <stdio.h>#include <stdlib.h>#define QUEUENUM 5typedef int DataType;typedef struct{ DataType _data[QUEUENUM];...原创 2019-07-04 17:14:38 · 194 阅读 · 0 评论 -
堆的实现
头文件heap.h#ifndef _HEAP_H#define _HEAP_Htypedef int HPDataType;typedef struct Heap{ HPDataType* data; int size; int capacity;}Heap;//向下调整法void adjustDown(Heap* hp, int n);//初始化,也就是建堆voi...原创 2019-08-16 18:19:28 · 100 阅读 · 0 评论 -
堆排序的实现
#include <stdio.h>#include <stdlib.h>//向下调整法static void adjustDown(int* data, int size, int n){ //n是要执行向下调整的节点 int cur = n; while (cur * 2 + 1 < size){ if (cur * 2 + 2 >= siz...原创 2019-08-17 18:12:05 · 68 阅读 · 0 评论 -
通过前序遍历的数组"ABD##GI##J###CE#HK###F##"构建二叉树,并得到二叉树的前序遍历,中序遍历,后序遍历
//前序遍历(递归)void BinaryTreePrevOrder(BTNode* root){ if (root){ putchar(root->data); BinaryTreePrevOrder(root->lchild); BinaryTreePrevOrder(root->rchild); }}//中序遍历(递归)void BinaryTre...原创 2019-08-26 17:58:58 · 365 阅读 · 0 评论 -
常见排序及算法实现(四)快速排序双指针法(一)
快速排序是Hoare于1962年提出的一种具有二叉树结构的交换排序方法.基本思想: 在一组待排序元素序列中,任取一个元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中的所有元素均小于基准值,右子序列中的所有元素均大于基准值,然后就是左右子序列重复该过程,一直到所有的元素都排列在相应的位置上位置.实现快速排序的方法常见的有双指针法,挖坑法,Hoare法.来看示例.假如有一组待...原创 2019-09-15 17:38:12 · 1960 阅读 · 0 评论 -
常见排序及算法实现(三)归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序.将两个有序表合并成一个有序表,称为二路归并.同样我们来从具体例子中来了解归并排序的思想.假设我们有一组数据为10 6 7 1 3 9 4 2在分...原创 2019-09-13 17:40:55 · 188 阅读 · 0 评论 -
对模拟环形队列的回顾
头文件 deque.h#ifndef _DEQUE_H#define _DEQUE_H#include <stdio.h>#include <stdlib.h>#define QUEUENUM 5typedef int DataType;typedef struct { DataType _data[QUEUENUM]; DataType* _hea...原创 2019-09-07 22:26:41 · 96 阅读 · 0 评论 -
判断一个二叉树是不是完全二叉树
//判断一个二叉树是不是完全二叉树(借助层序遍历)int BinaryTreeComplete(BTNode* root){ Queue qu; BTNode* cur; int tag = 0; QueueInit(&qu); QueuePush(&qu, root); while (!QueueIsEmpty(&qu)){ cur = Que...原创 2019-09-06 19:31:05 · 315 阅读 · 0 评论 -
二叉树的非递归中序遍历
//非递归中序遍历void BinaryTreeInOrderNonR(BTNode* root){ BTNode* cur = root; Stack st; StackInit(&st, 100);#if 0 while (1){ for (; cur; cur = cur->lchild){ StackPush(&st, cur); }...原创 2019-08-29 17:46:42 · 112 阅读 · 0 评论 -
常见排序及算法实现(四)快速排序双指针法(二)
假如有一组待排序的数据为9 1 2 7 6 3 4 5 10 8来看双指针的第二种做法:类似于双指针的第一种做法,不同的是我们这次用中间的元素作为基准值首先同样是两个指针a = start, b = end - 1;等一下再说明尾指针为什么放在end - 1的位置然后 取 mid = (start + end) / 2;接下来我们将mid位置的元素6与最后一个元素8交换,数据变为...原创 2019-09-16 20:26:05 · 714 阅读 · 1 评论 -
二叉树的非递归前序遍历
二叉树的非递归前序遍历,需要借助栈(栈又是由顺序表实现的)栈的实现头文件 Stack.h#ifndef _Stack_H_#define _Stack_H_#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "BTree.h"typedef BTNode* S...原创 2019-08-28 19:29:01 · 326 阅读 · 0 评论 -
二叉树的层序遍历
二叉树的层序遍历需要借助于队列,而队列又由单链表实现对无头单向非循环链表的回顾源文件 BTree.c//层序遍历,层序遍历需要借助队列(队列由单链表实现)void BinaryTreeLevelOrder(BTNode* root){Queue qu;BTNode* cur; QueueInit(&qu); QueuePush(&qu, root); whil...原创 2019-08-27 17:44:52 · 323 阅读 · 0 评论 -
带头双向循环链表增删操作
头文件List.h存放函数声明#ifndef _LIST_H#define _LIST_H#include <stdio.h>#include <stdlib.h>#include <assert.h>typedef int LTDataType;typedef struct ListNode{ LTDataType _data; str...原创 2019-07-03 17:31:18 · 81 阅读 · 0 评论 -
关于文件结束的判定
在文件的读取过程中,feof函数的返回值不能直接用来判断文件是否结束.正确的用法是当文件读取结束时,判断是读取失败结束,还是遇到了文件尾结束.判断文本文件的读取是否结束,需要判断其返回值是否为EOF(fgetc),或者NULL(fgets).也就是说用fgetc获取文件内容时,需要判断是否为EOF(文件结束标志).用fgets获取文件内容时,需要判断其返回值是否为NULL.对于二进制文件的...原创 2019-06-23 19:26:03 · 1249 阅读 · 0 评论 -
C语言对于文件的基本读写操作
之前已经对文件有了一些基本的了解,比如文件的定义,类型等,最重要的是关于C语言中对文件进行操作时的打开和关闭.C语言文件操作的基本认识(文件是什么,文件的类型,文件指针,文件的打开和关闭)接下来就来看C语言中对于文件的读写操作.字符输入函数和字符输出函数fgetc与fputc(每次获取一个字符)先来看fgetc,fgetc是从文件中获取一个字符#define _CRT_SECURE_...原创 2019-06-18 16:40:36 · 2593 阅读 · 1 评论 -
一级指针,二级指针,指针和数组,指针数组,数组指针
首先先来对指针就行一个简单的回顾.指针(指针是什么,指针和指针的类型)在对指针有了一个简单的了解之后,接下来我们就来看看指针更深层次的内容.在我们的一级指针中,其实它不光光能指向一个数字int i = 10;int* p = &i;除此之外,还有字符指针,数组指针,函数指针等等.首先我们来看字符指针,通过前面对指针的简单回顾,我们知道,在指针的类型中有一种指针类型为字符指针...原创 2019-06-01 17:30:45 · 227 阅读 · 0 评论 -
自定义类型:结构体(结构体声明,结构体的自引用,结构体变量的定义和初始化)
结构体的声明struct tag{ member-list;}variable-list;结构是一些值的集合,这些值称为成员变量.结构的每个成员可以是不同类型的变量.先来看一个例子,假如我们现在想要描述一个学生:struct stu{ char name[20]; //名字 int age; //年龄 char sex[5]; //性别 char id[20]; //学号...原创 2019-06-06 16:10:59 · 3120 阅读 · 1 评论 -
位段
自定义类型:结构体(结构体声明,结构体的自引用,结构体变量的定义和初始化)关于结构体的内存对齐结构体传参说完了结构体,就要说一说结构体实现位段的能力了.那么位段是什么呢?位段的声明和结构是类似的,但是会有两个不同:1.位段的成员必须是int, unsigned int, signed int 或 char2.位段的成员名后边有一个冒号和一个数字比如:...原创 2019-06-12 17:51:02 · 116 阅读 · 0 评论 -
对于字符函数和字符串函数的介绍(下),strstr,strtok,strerror,memcpy,memmove
strstr函数的介绍char* strstr(const char* str1,const char* str2);strstr函数是在第一个字符串中查找第二个字符串是否存在.找到后将首地址返回,没找到就返回NULL.strstr例子#include <stdio.h>#include <stdlib.h>//strstr使用int main(){ ch...原创 2019-06-05 17:27:40 · 265 阅读 · 0 评论 -
关于strstr的用法以及模拟实现
#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){ char str1[] = "abcdefggggggg"; char str2[] = "bcdef"; char* p = NULL; p = strstr(str1, str2) puts(p); sys...原创 2019-05-28 15:49:28 · 206 阅读 · 0 评论 -
关于函数指针,函数指针数组以及函数指针数组的用途(计算器实现)
在之前的学习中我们已经知道了,数组是一个存放相同类型数据的存储空间,而指针数组就是一个用来存放指针变量的数组,比如:int* arr[10]; //数组的每个元素是int*既然有了指针数组,那么我们能不能把函数的地址也都存到一个数组当中去?答案是肯定的,这样的一个数组就叫做函数指针数组,比如:int (*parr[10])();parr首先与[]结合表示一个数组名,这也就说明parr是数组...原创 2019-05-23 16:34:06 · 229 阅读 · 0 评论 -
模拟实现memcpy,memmove以及memcpy与memmove的不同
首先看memcpy的用法void* memcpy(void* destination, const void* source, size_t num);函数memcpy是从source的位置开始向后复制num个字节的数据到destination的内存位置.这个函数在遇到’\0’时不会停下来.如果source和destination有任何的内存重叠,复制的结果都是未定义的!接下来看memc...原创 2019-05-30 14:50:44 · 181 阅读 · 0 评论 -
对于数组指针和指针数组的理解及其应用
在之前的学习中,我们已经简单了解过了数组指针和指针数组(数组指针,指针数组,二级指针)我们知道指针数组其实就一个用来存放指针的数组.这里先做一个指针数组简单的回顾.int* arr[10]; //这是一个存放整型指针的数组char* arr[10]; //存放字符型指针的数组char** arr[5]; //存放二级字符型指针的数组而容易与之混淆的就是数组指针.数组指针其实就是指针,这个...原创 2019-05-21 15:31:27 · 3639 阅读 · 0 评论 -
枚举和联合(共用体)
从名字来看,枚举的意思就是列举,把可能的取值列举出来.从我们的日常生活中来看,有很多例子:1.一周的星期一到星期日是固定的7天,就可以列举出来.2.从性别来看,有男,女两种.3.月份也类似于一周,有固定的十二个月,也可以列举出来.类似于这样的例子有很多,碰到这样的情况,我们就可以使用枚举了.枚举类型的定义先来看几个例子:enum Day{ //星期 Monday, Tuesda...原创 2019-06-13 15:47:03 · 1010 阅读 · 0 评论 -
关于结构体的内存对齐
结构体内存对齐自定义类型:结构体(结构体声明,结构体的自引用,结构体变量的定义和初始化)在掌握结构体的基本使用之后,我们就要深入讨论一个问题了,就是关于计算结构体的大小.先来看几个例子:#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <string....原创 2019-06-09 15:48:05 · 133 阅读 · 0 评论 -
关于动态内存分配以及常见的动态内存函数的介绍
在之前的学习中我们已经知道的内存开辟方式有:int val = 20; //在栈空间上开辟四个字节char arr[10] = { 0 }; //在栈空间上开辟10个字节的连续空间在上面这两种开辟空间的方式有两个特点:1.空间开辟的大小是固定的.2.数组在声明的时候,一定要指定数组的长度,它所需要的内存在编译时分配.在我们的实际应用中,对于所需要的空间需求,往往不仅仅是上面两种情况!...原创 2019-06-14 17:46:38 · 502 阅读 · 0 评论 -
给定一个链表,判断链表中是否有环
无头单向非循环链表实现void SListHaveCircle(SList* plist){ assert(plist); SListNode* fast = plist->_head; SListNode* slow = plist->_head; while (slow && fast && fast->_next){ slow ...原创 2019-07-01 17:21:41 · 347 阅读 · 0 评论 -
简单了解有关算法的时间复杂度和空间复杂度
首先是关于算法效率的问题.算法效率的分析一般可分为两种:一种是时间效率,一种是空间效率.时间效率被称为时间复杂度,而空间效率被称为空间复杂度.我们通常用时间复杂度去衡量一个算法的运行速度,而空间复杂度主要衡量的是一个算法所需要的额外空间.在计算机发展的早些时候,由于计算机的存储容量比较小,所以对于空间复杂度特别在乎,但是经过这么多年计算机行业的迅速发展,我们的计算机容量已经达到了一种相对较高...原创 2019-06-25 20:38:14 · 3124 阅读 · 0 评论 -
C语言实现计算文件大小
首先,先介绍两个对C语言文件操作的函数fseek函数,用来根据文件指针的位置和偏移量来定位文件指针int fseek(FILE* stream, long int offset, int origin);offset表示偏移量.这里的origin参数一般有三种情况1.SEEK_CUR,表示文件指针的当前位置(也可用1来表示)2.SEEK_SET,表示文件指针的开始位置(也可用0来表示...原创 2019-06-20 19:20:12 · 2189 阅读 · 0 评论 -
对于字符函数和字符串函数的介绍(上),strlen,strcpy和strncpy,strcat和strncat,strcmp和strncmp
求字符串长度 strlen长度不受限制的字符串函数 strcpy strcat strcmp长度受限制的字符串函数介绍 strncpy strncat strncmp字符串查找 strstr strtok错误信息报告 strerror内存操作函数 memcpy memmove memset memcmpC语言中对字符和字符串的处理很多,但是C语言本身没有字符串类型,字符串通常放在常量字...原创 2019-06-04 20:23:01 · 366 阅读 · 0 评论 -
C语言文件操作的基本认识(文件是什么,文件的类型,文件指针,文件的打开和关闭)
什么文件磁盘上的文件是文件.一般情况下,在我们的程序设计中,会谈到的文件有两种:程序文件,数据文件程序文件包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe).数据文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件.接下来我们主要讨论数据文件.之前我们所处理数据的输...原创 2019-06-16 15:58:40 · 1918 阅读 · 0 评论 -
常见的动态内存错误
对NULL指针的解引用操作void test(){ int* p = (int*)malloc(sizeof(int)); *p = 20; //如果p的值时NULL,就会有问题 free(p);}对动态开辟空间的越界访问void test(){ int i = 0; int* p = (int*)malloc(sizeof(int) * 10); if (NULL == p...原创 2019-06-15 19:41:26 · 288 阅读 · 0 评论