
数据结构
canvass
Practice makes perfect
展开
-
判断链表的回文结构
OJ链接:链表的回文结构解题方法:快慢指针法,如下图所示:找出链表中间位置 逆置后一半链表 将逆序后的与原来的前半部分作比较代码/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {}};*/class PalindromeList {public: bool chkPalindrome(ListNode* A.原创 2020-08-11 21:55:21 · 122 阅读 · 0 评论 -
循环链表II
OJ链接:循环链接II方法一:快慢指针使用快慢指针,快指针每次走2步,慢指针每次走1步。当有环相遇时,说明快指针走过的路程是慢指针的两倍,假设链表头结点到环入口位置距离为a,环的入口与相遇节点位置距离为b,环的长度为R,我们计算快慢指针所走过的距离:d(fast)=a+b+n*R, d(slow)=a+b。快指针的速度是慢指针的两倍,相同时间,快指针所走过的路程应该是慢指针所走过路程的两倍,于是:d(fast)=2*d(slow)。所以有:a=n*R-b。当n = 1时,也就是快.原创 2020-08-11 17:13:49 · 143 阅读 · 0 评论 -
环形链表
OJ链接:环形链表思路一:快慢指针我们定义两个指针,初始位置都放在头节点的地方,然后快慢指针一起走,快指针一次走两步(需要注意边界条件),慢指针一次走一步,如果快指针走到nullptr,该链表就不带环;如果快慢指针相遇,该链表就带环。例如:两个人在操场跑步,一个人的速度是另一个人的两倍,如果跑的快的人追上跑的慢的人,那么快的人必然超过慢的人一圈。那么在链表中,也是一样的。代码/** * Definition for singly-linked list. * struct List.原创 2020-08-11 15:54:28 · 186 阅读 · 0 评论 -
和并两个有序链表
OJ链接:合并两个有序链表解题思路:依此比较两个链表,取较小值,进行尾插,返回head。/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */typedef struct ListNode Node;struct ListNode* mergeTwoLists(struct ListNode* l1, struct原创 2020-08-11 10:41:47 · 120 阅读 · 0 评论 -
快速排序(hoare法,刨坑法,前后指针法)及非递归实现
单趟排序:将比key小和相等的放在左边,将比key大和相等的放到右边单趟排序的变形1.hoare法,2.刨坑法,3.前后指针法。hoare法最右边做key,左边先走;左边做key,右边先走。void Swap(int *a, int *b){ int tmp = *a; *a = *b; *b = tmp;}int HoareSort(int *a, int b...原创 2020-03-21 20:28:30 · 377 阅读 · 0 评论 -
直接选择排序
一次选两个数,最小的放第一个位置,最大的放最后一个位置v#include<stdio.h>void Swap(int *p1, int *p2){ int tmp = *p1; *p1 = *p2; *p2 = tmp;}void PrintArray(int *a, int n){ for (int i = 0; i < n; ++i) { p...原创 2020-03-19 22:36:46 · 111 阅读 · 0 评论 -
二叉树基础面试题2(力扣)
1. 二叉树的前序遍历题目描述:给定一个二叉树,返回它的前序遍历。int TreeSize(struct TreeNode* root){ if(root==NULL) return 0; return 1+TreeSize(root->left)+TreeSize(root->right);}void _preorderTraversal...原创 2020-03-13 17:10:08 · 150 阅读 · 0 评论 -
二叉树基础面试题1(力扣)
分治递归的思想解决递归问题两个条件:1、子问题(一颗树分成3个部分:根+左子树+右子树) 2、返回条件(空树)1.单值二叉树题目描述:如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时,才返回true;否则返回 false。bool isUnivalTree(struct TreeNode* root){ if(roo...原创 2020-03-12 17:38:54 · 201 阅读 · 0 评论 -
堆的实现
堆的性质堆中某个节点的值总是不大于或不小于其父亲节点的值; 堆总是一颗完全二叉树。堆的实现Heap.h原创 2020-03-03 09:33:31 · 170 阅读 · 0 评论 -
判断两个单链表是否相交,若相交则返回两个链表相交的结点
首先将两个链表进行"对齐".(两个链表相交也就是说,从相交的结点开始,后面两个链表内容相同).思路首先通过链表遍历,求出两个链表的长度,得到其差值.创建两个指针分别指向这两个链表的头位置.然后对较长的链表开始从头遍历差值部分,接下来让两个指针一起向前走,若相遇则得到两链表相交结点,否则两链表不相交.SListNode *getIntersectionNode(Slist *list...原创 2019-09-19 20:39:19 · 176 阅读 · 0 评论 -
归并排序
采用分治法void dealMergeSort(int * src, int * tmp, int start, int end){ if (start >= end) { return; } int mid = (start + end) / 2; dealMergeSort(src, tmp, start, mid); dealMergeSort(src, tm...原创 2019-08-22 23:34:11 · 103 阅读 · 0 评论 -
希尔排序
希尔排序是对直接插入排序的优化,数组越有序,插入排序更快void ShellSort(int * src, int n){ int i, j, k; int gap, tmp; for (gap = n / 2; gap; gap /= 2) { for (k = 0; k < gap; k++) { for (i = gap + k; i < n; ...原创 2019-08-22 23:31:51 · 105 阅读 · 0 评论 -
直接插入排序
核心思想:1,拷贝 2,平移,3,插入void InsertSort(int * src, int n){ int i, j; int tmp; for (i = 1; i < n; i++) { tmp = src[i]; for (j = i; j > 0 && src[j - 1] > tmp; j--) { src[...原创 2019-08-22 23:27:00 · 106 阅读 · 0 评论 -
用前序构建二叉树(递归实现)
#ifndef _BTREE_H_#define _BTREE_H_typedef char BTDataType;typedef struct BinaryTreeNode{ BTDataType data; struct BinaryTreeNode* lchild; struct BinaryTreeNode* rchild;}BTNode;BTNode *Binar...原创 2019-08-17 20:48:40 · 339 阅读 · 0 评论 -
堆排序
堆 ,是一种特殊的完全二叉树,采用顺序存储核心思想:向下调整算法,创建堆,堆顶和最后一个交换,排序#include<stdio.h>#include<stdlib.h>static void adjustDown(int *data, int size, int m){ int cur = m; int n; while (cur*2+1<s...原创 2019-08-17 20:31:09 · 116 阅读 · 0 评论 -
冒泡排序
设有一个大小为N的无序序列,要进行(n-1)趟比较。冒泡排序就是要每趟排序过程中通过两两比较,找到第i个小(大)的元素,将其往上排。经过第1趟比较数组中最大的元素放在了最右边,经过第2趟比较数组中第2大的元素放在了倒数第2个位置,经过第3趟比较数组中第3大的元素放在了倒数第3个位置, ... ,经过第n趟比较,数组就有序了。图示过程:#include<stdio....原创 2019-08-20 23:22:07 · 334 阅读 · 0 评论 -
编写函数 要求逆置单链表(不带头节点)
void SListReverse(SList* plist){ assert(plist->_head);#if 0 SListNode *tmp = plist->_head->_next; SListNode *cur = plist->_head; while (tmp) { cur ->_next= tmp->_next; tm...原创 2019-07-28 13:07:13 · 888 阅读 · 0 评论 -
二叉树前序,中序,后序遍历(递归实现)
void BinaryTreePrevOrder(BTNode* root){ if (root) { putchar(root->data); BinaryTreePrevOrder(root->lchild); BinaryTreePrevOrder(root->rchild); }}void BinaryTreeInOrder(BTNode* r...原创 2019-08-18 17:12:56 · 119 阅读 · 0 评论 -
二叉树层次遍历(用队列实现)
核心思想:首先根节点入队,若队列非空则做循环,若根节点有左右孩子,则左右孩子入队,第一个节点出队,循环直到队列为空。#ifndef _BTREE_H_#define _BTREE_H_typedef char BTDataType;typedef struct BinaryTreeNode{ BTDataType data; struct BinaryTreeNode* lc...原创 2019-08-18 17:21:24 · 6610 阅读 · 0 评论 -
用非递归实现二叉树前序遍历(用栈)
核心思想:根节点和左孩子直接遍历,若有右孩子,则入栈。没有左右孩子,直接出栈顶元素。#ifndef _BTREE_H_#define _BTREE_H_typedef char BTDataType;typedef struct BinaryTreeNode{ BTDataType data; struct BinaryTreeNode* lchild; struct Bin...原创 2019-08-18 17:28:11 · 868 阅读 · 1 评论 -
用非递归实现二叉树中序遍历
核心思想:将根节点和左孩子都入栈,没有左孩子就出栈顶元素打印,进右孩子,有右孩子就将右孩子(相当于根节点)和左孩子入栈。void BinaryTreeInOrderNonR(BTNode* root){ BTNode *cur = root;//root是根节点 Stack st; StackInit(&st, 100); while (cur || !Stack...原创 2019-08-19 23:35:09 · 131 阅读 · 0 评论 -
用非递归实现二叉树后序遍历
核心思想:将根节点和左孩子都入栈,置为0,没有左孩子,栈顶元素置为1,右孩子和左孩子入栈,置为0,没有左孩子,置为1,没有右孩子循环出栈打印(打印置为1的)。void BinaryTreePostOrderNonR(BTNode* root){ char tag[64];//数组最大不会超过树的深度 BTNode *cur = root; Stack st; StackInit...原创 2019-08-19 23:38:48 · 655 阅读 · 0 评论 -
判断一颗树是否为完全二叉树
核心思想:1,有右孩子无左孩子不是完全二叉树 2,有一个节点没有右孩子,后边有非叶子节点不是完全二叉树int BinaryTreeComplete(BTNode* root)//判断是否为完全二叉树{ Queue qu; BTNode * cur; int tag = 0; QueueInit(&qu); QueuePush(&...原创 2019-08-19 23:41:20 · 401 阅读 · 0 评论 -
D27 循环队列基本实现
#ifndef _DEQUEUE_H#define _DEQUEUE_H#include <stdio.h>#include<stdlib.h>#define QUEUENUM 100typedef int DataType;typedef struct{ DataType _data[QUEUENUM]; DataType *head; Data...原创 2019-07-04 22:44:17 · 154 阅读 · 0 评论 -
D26 带头双向循环链表的增删实现
#ifndef _LIST_H#define _LIST_H#include<stdio.h>#include<stdlib.h>typedef int LTDataType;typedef struct ListNode{ LTDataType _data; struct ListNode* _next; struct ListNode...原创 2019-07-03 16:51:13 · 130 阅读 · 0 评论 -
D25. 无头单向非循环链表的实现
单链表#ifndef _SLIST_H_#define _SLIST_H_/*链表遍历for(cur = head; cur; cur = cur->next) 无头单向非循环链表{cur;}for(cur = head->next; cur != head; cur = cur->next) 带头双向循环链表{cur;...原创 2019-06-26 18:14:42 · 112 阅读 · 0 评论 -
D24. 顺序表的动态存储
// 顺序表的动态存储 #ifndef _SEQLIST_H_#define _SEQLIST_H_#include<stdio.h>#include<stdlib.h>#include<assert.h>typedef int SLDataType; //相当于给int起一个datatype的别称,及datatype就是inttypede...原创 2019-06-26 17:17:55 · 148 阅读 · 0 评论 -
快速排序(双指针法,刨坑法,hoare法)
分割策略:#include <stdio.h>#include <stdlib.h>void InsertSort(int * src, int n){ int i, j; int tmp; for (i = 1; i < n; i++) { tmp = src[i]; for (j = i; j > 0 && ...原创 2019-08-24 23:30:32 · 650 阅读 · 0 评论 -
如何快速查找到一个单链表的中间位置?编写函数实现
核心思想:快慢指针首先指向第一个节点,快指针每次走2个结点,慢指针每次走1个结点,当快指针走完链表,慢指针刚好走到中间。 当前快指针走完链表时,慢指针刚好走到 中间结点。 实际上当结点数是奇数时 慢指针走到中间结点, 当结点数是偶数时,此时中间结点有2个,此时慢指针指向靠前那个结点。 举个例子 1 3 5 7 9 快指针第一次走到 5 第二次走到 9 然后链...原创 2019-08-04 14:09:16 · 1086 阅读 · 0 评论