个人知识库 个人知识库
首页
关于
  • C语言
  • CPlusPlus
  • Linux
  • PHP
  • Nginx
  • MySQL
  • Redis
  • Docker
  • Kubernetes
  • SRS
阅读
常用工具
  • 分类
  • 标签
  • 归档
GitHub

Agnes001

坚持是一件很伟大的事业
首页
关于
  • C语言
  • CPlusPlus
  • Linux
  • PHP
  • Nginx
  • MySQL
  • Redis
  • Docker
  • Kubernetes
  • SRS
阅读
常用工具
  • 分类
  • 标签
  • 归档
GitHub
  • C语言

  • CPlusPlus

  • Lua技术栈

  • edoyun

  • 内存管理

  • 数据结构

    • 链表
    • 数据结构与算法
    • 算法
      • 冒泡排序
      • 选择排序
      • 插入排序
      • 希尔排序
      • 快速排序
      • 归并排序
      • 堆排序
      • c++模板类与数据结构基础
        • 链表类_链式存储设计与实现
        • 栈类_链式存储设计与实现
        • 队列类_链式存储设计与实现
        • 链表类_顺序存储设计与实现
        • 栈类_顺序存储设计与实现
        • 队列类_顺序存储设计与实现
  • 网络编程

  • Linux

  • 池化技术

  • 操作系统

  • python

  • 编程技术
  • 数据结构
Agnes001
2022-01-10

指针

https://www.runoob.com/w3cnote_genre/algorithm

# 冒泡排序

外层循环控制循环次数,内层循环进行比较

void BubbleSort(int arr[], int length){
	int flag = 0;
	for (int i = 0; i < length && flag == 0; i++){
		flag = 1; //认为已经排序好
		for (int j = length - 1; j > i; j--){
			if (arr[j - 1] < arr[j]){
				flag = 0;
				Swap(&arr[j - 1], &arr[j]);
			}
		}
	}
}

# 选择排序

每次循环选出最小的数,然后与外层循环的下标对应的变量进行交换

void SelectSort(int arr[],int length){	
	//选择排序是不是减少交换次数 
	for (int i = 0; i < length;i ++){
		int min = i;
		for (int j = i + 1; j < length; j++){
			if (arr[j] < arr[min]){
				min = j;
			}
		}
		if (min != i){
			Swap(&arr[min],&arr[i]);
		}
	}
}

# 插入排序

从下标1开始,与之前的数据进行比较,比较过程中前边的数据都是已经排好序的

void InsertSort(int arr[], int length){
	int j;
	for (int i = 1; i < length; i++){

		if (arr[i] < arr[i - 1]){

			int temp = arr[i];
			for (j = i - 1; j >= 0 && temp < arr[j]; j--){
				arr[j + 1] = arr[j];
			}
			arr[j + 1] = temp;
		}
	}
}

# 希尔排序

确定增量,increasement = increasement / 3 + 1 (步长 = 步长 / 3 + 1) 根据增量分为若干子序列,分别进行插入排序;减小增量再进行排序...

void ShellSort(int arr[], int length){
	int increasement = length;
	int i, j,k;

	do{
		//确定分组的增量
		increasement = increasement / 3 + 1;
		for (i = 0; i<increasement;i++){
			
			for (j = i + increasement; j < length; j += increasement){		
				
				if (arr[j] < arr[j-increasement] ){
					
					int temp = arr[j];
					for (k = j - increasement; k >= 0 && temp < arr[k];k-=increasement){
						arr[k + increasement] = arr[k];
					}
					arr[k + increasement] = temp;
				}
			}
		}
	} while (increasement > 1);
}

# 快速排序

分治法,找到基准数,从右向左进行比较,然后再从左到右比较

void QuickSort(int arr[], int start, int end){	
	int i = start;
	int j = end;
	//基准数
	int temp = arr[start]; 
	if (i < j){
		while (i < j){
			//从右向左去找比基准数小的
			while (i<j && arr[j] >= temp ){
				j--;
			}
			//填坑
			if(i < j){
				arr[i] = arr[j];
				i++;
			}
			//从左向右 找比基准数大的数
			while (i < j && arr[i] < temp){
				i++;
			}
			//填坑
			if (i < j){
				arr[j] = arr[i];
				j--;
			}
		}
		//把基准数放到i位置
		arr[i] = temp;
		//对左半部分进行快速排序
		QuickSort(arr, start, i - 1);
		//对右半部分进行快速排序
		QuickSort(arr, i + 1, end);
	}
}

# 归并排序

https://www.cnblogs.com/chengxiao/p/6194356.html 分治法,基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了? 可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。

//合并算法 从小到大
void Merge(int arr[], int start, int end, int mid, int* temp){

	int i_start = start;
	int i_end = mid;
	int j_start = mid + 1;
	int j_end = end;

	//表示辅助空间有多少个元素
	int length = 0;

	//合并两个有序序列
	while (i_start <= i_end && j_start <= j_end){

		if(arr[i_start] < arr[j_start]){
			temp[length] = arr[i_start];
			length++;
			i_start++;
		}else{
			temp[length] = arr[j_start];
			j_start++;
			length++;
		}
	}

	//i这个序列
	while (i_start <= i_end){
		temp[length] = arr[i_start];
		i_start++;
		length++;
	}

	//j序列
	while (j_start <= j_end){
		temp[length] = arr[j_start];
		length++;
		j_start++;
	}

	//辅助空间数据覆盖原空间
	for (int i = 0; i < length;i++){
		arr[start + i] = temp[i];
	}
}

//归并排序
void MergeSort(int arr[],int start,int end,int* temp){

	if (start >= end){
		return;
	}

	int mid = (start + end) / 2;
	//分组
	//左半边
	MergeSort(arr,start,mid,temp);
	//右半边
	MergeSort(arr, mid + 1, end,temp);
	//合并
	Merge(arr,start,end,mid,temp);
}

# 堆排序

https://www.cnblogs.com/chengxiao/p/6129630.html

/*
	@param myArr 待调整的数组
	@param index 待调整的结点的下标
	@param len 数组的长度
*/
void HeapAdjust(int arr[], int index, int len){

	//先保存当前结点的下标
	int max = index;
	//保存左右孩子的数组下标
	int lchild = index * 2 + 1;
	int rchild = index * 2 + 2;

	if (lchild < len && arr[lchild] < arr[max]){
		max = lchild;
	}

	if (rchild < len && arr[rchild] < arr[max]){
		max = rchild;
	}

	if (max != index){
		//交换两个结点
		MySwap(arr,max,index);
		HeapAdjust(arr,max,len);
	}
}

//堆排序
void HeapSort(int myArr[], int len){

	//初始化堆
	for (int i = len / 2 - 1; i >= 0; i --){
		HeapAdjust(myArr,i,len);
	}

	//交换堆顶元素和最后一个元素
	for (int i = len - 1; i >= 0; i --){
		MySwap(myArr, 0, i);
		HeapAdjust(myArr, 0, i);
	}

}

# c++模板类与数据结构基础

:所有容器提供的都是值(value)语意,而非引用(reference)语意。容器执行插入元素的操作时,内部实施拷贝动作。所以STL容器内存储的元素必须能够被拷贝(必须提供拷贝构造函数)。

# 链表类_链式存储设计与实现

//LinkList.hpp
#ifndef LINKLIST_HPP
#define LINKLIST_HPP
#include <string>
//c++模板完成单向链表

//结点结构
template<class T>
class ListNode{
public:
	T data;  //数据域
	ListNode* next; //指针域
};

//定义链表类
template<class T>
class LinkList{
public:

	//构造函数
	LinkList():length(0),head(NULL){}

	//链表操作相关API
	//设置链表长度
	void setLength(int length){
		if (length < 0){
			return;
		}
		this->length = length;
	}
	//获得链表长度
	int getLength(){
		return this->length;
	}
	//设置链表头结点
	void setHead(ListNode<T>* head){
		this->head = head;
	}
	//获得链表的头结点
	ListNode<T>* getHead(){
		return this->head;
	}
	//插入元素
	int Insert(int pos, T value){
		
		//创建结点
		ListNode<T>* newnode = new ListNode<T>();
		newnode->next = NULL;
		newnode->data = value;

		//第一次插入
		if (this->head == NULL){
			this->head = newnode;
			this->length++;
			return 0;
		}

		//头插法
		ListNode<T>* pCurrent = head;
		if(pos == 0){
			newnode->next = pCurrent;
			this->head = newnode;
			this->length++;
			return 0;
		}

		//找到插入位置
		//ListNode<T>* pCurrent = head;
		for (int i = 1; i < pos;i++){
			if (pCurrent->next == NULL){
				break;
			}
			pCurrent = pCurrent->next;
		}
		//插入新的结点
		newnode->next = pCurrent->next;
		pCurrent->next = newnode;
		this->length++;
	}

	//删除某个位置的结点
	int Delete(int pos){
		
		if (this->length == 0){
			return -1;
		}
		if(pos > this->length || pos < 0){
			return -2;
		}

		//头删法
		if (pos == 0){
			ListNode<T>* pDel = this->head;
			this->head = pDel->next;
			this->length--;
			delete pDel;
			return 0;
		}

		//找删除的位置
		ListNode<T>* pCurrent = head;
		for (int i = 1; i < pos;i++){
			pCurrent = pCurrent->next;
		}

		ListNode<T>* pDel = pCurrent->next;
		//重新连接结点
		pCurrent->next = pDel->next;
		//删除结点
		delete pDel;
		this->length--;
	}

	//判断链表是否为空
	bool IsEmpty(){
		if (this->length == 0){
			return true;
		}
		return false;
	}
	~LinkList(){
		while (this->length){
			Delete(0);
		}
	}
private:
	int length; //保存结点数量
	ListNode<T>* head;
};

#endif
//LinkListTest.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"LinkList.hpp"
using namespace std;

//测试单向链表容器
void test01(){

	//创建容器
	LinkList<int> list;
	//向容器中插入数据
	for (int i = 0; i < 10; i++){
		list.Insert(list.getLength(), i);
	}
	//遍历打印链表
	ListNode<int>* pCurrent = list.getHead();
	while (pCurrent != NULL){
		cout << pCurrent->data << " ";
		pCurrent = pCurrent->next;
	}
	cout << endl;


	//删除结点
	list.Delete(0);
	list.Delete(1);

	//遍历打印链表
	pCurrent = list.getHead();
	while (pCurrent != NULL){
		cout << pCurrent->data << " ";
		pCurrent = pCurrent->next;
	}
	cout << endl;
}


//Teacher类
class Teacher{
public:
	Teacher(){}
	Teacher(string name, int age){
		this->m_name = name;
		this->m_age = age;
	}
	//拷贝构造
	Teacher(const Teacher& t){
		this->m_name = t.m_name;
		this->m_age = t.m_age;
	}
	//重载=操作符
	Teacher operator=(Teacher& t){
		this->m_name = t.m_name;
		this->m_age = t.m_age;
		return *this;
	}
public:
	string m_name;
	int m_age;
};

//容器中存储对象 重点:容器元素都是值寓意,而非引用寓意
void test02(){

	//创建两个Teacher类的实例
	Teacher t1("aaa", 10), t2("bbb", 20);
	//创建容器
	LinkList<Teacher> list;
	//向list中插入元素
	list.Insert(0, t1);
	list.Insert(0, t2);
	//打印容器中的元素的值
	ListNode<Teacher>* pCurrent = list.getHead();
	while (pCurrent != NULL){
		cout << "Name:" << pCurrent->data.m_name << " Age:" << pCurrent->data.m_age << endl;
		pCurrent = pCurrent->next;
	}
	list.Delete(1);
	//打印容器中的元素的值
	pCurrent = list.getHead();
	while (pCurrent != NULL){
		cout << "Name:" << pCurrent->data.m_name << " Age:" << pCurrent->data.m_age << endl;
		pCurrent = pCurrent->next;
	}

}

//容器中存储指针
void test03(){

	//创建两个Teacher类的实例
	Teacher t1("aaa", 10), t2("bbb", 20);
	//创建容器
	LinkList<Teacher*> list;
	//插入元素
	list.Insert(0, &t1);
	list.Insert(0, &t2);

	//打印容器中的元素的值
	ListNode<Teacher*>* pCurrent = list.getHead();
	while (pCurrent != NULL){
		cout << "Name:" << pCurrent->data->m_name << " Age:" << pCurrent->data->m_age << endl;
		pCurrent = pCurrent->next;
	}
}

int main(){

	//test01();
	//test02();
	test03();

	system("pause");
	return EXIT_SUCCESS;
}

# 栈类_链式存储设计与实现

//LinkStack.hpp
#ifndef LINKQUEUE_HPP
#define LINKQUEUE_HPP

//结点结构
template<class T>
class LinkNode{
public:
	T data;
	LinkNode* next;
};

//队列类
template<class T>
class LinkQueue{
public:
	//初始化链式队列
	LinkQueue(){
		pFront = NULL;
		pBack = NULL;
		mLength = 0;
	}
	//获得队列长度
	int getLength(){
		return this->mLength;
	}
	//队列加入元素
	void Push(T data){
		
		//创建新的结点
		LinkNode<T>* newnode = new LinkNode<T>();
		newnode->data = data;
		newnode->next = NULL;

		//判断是不是第一次插入
		if (pFront == NULL && pBack == NULL){
			pFront = newnode;
			pBack = newnode;
			this->mLength++;
			return;
		}

		//其他情况
		this->pBack->next = newnode;
		this->pBack = newnode;
		this->mLength++;

		return;
	}

	T& Front(){
		return this->pFront->data;
	}

	void Pop(){

		if (this->mLength == 0){
			return;
		}

		//当队列中只有一个元素的时候
		if (this->mLength == 1){
			delete this->pFront;
			this->pFront = NULL;
			this->pBack = NULL;
			this->mLength--;
			return;
		}

		//其他情况
		LinkNode<T>* pDel = this->pFront;
		this->pFront = pDel->next;
		delete pDel;
		this->mLength--;
		return;
	}
	~LinkQueue(){
		while (this->mLength > 0){
			Pop();
		}
	}
private:
	LinkNode<T>* pFront; //队头
	LinkNode<T>* pBack; //队尾
	int mLength; //队列长度
};
#endif
//LinkStackTest.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include"LinkStack.hpp"
using namespace std;

//栈容器存储基础数据类型
void test01(){
	
	//创建栈容器
	LinkStack<int> lstack;
	//向栈中加入元素
	for (int i = 10; i < 20;i++){
		lstack.Push(i);
	}
	//打印栈中元素
	while (lstack.getLength() > 0){
		int val = lstack.Top();
		cout << val << " ";
		lstack.Pop();
	}
	cout << endl;
}

//栈容器存储对象

//Teacher类
class Teacher{
public:
	Teacher(){}
	Teacher(string name, int age){
		this->m_name = name;
		this->m_age = age;
	}
	//拷贝构造
	Teacher(const Teacher& t){
		this->m_name = t.m_name;
		this->m_age = t.m_age;
	}
	//重载=操作符
	Teacher operator=(Teacher& t){
		this->m_name = t.m_name;
		this->m_age = t.m_age;
		return *this;
	}
public:
	string m_name;
	int m_age;
};

void test02(){

	//创建栈
	LinkStack<Teacher> lstack;
	//插入数据
	Teacher t1("aaa", 10), t2("bbb", 20),t3("ccc",30);
	lstack.Push(t1);
	lstack.Push(t2);
	lstack.Push(t3);
	//遍历打印
	while (lstack.getLength() > 0){
		Teacher teahcer = lstack.Top();
		cout << "Name:" << teahcer.m_name << " Age:" << teahcer.m_age << endl;;
		lstack.Pop();
	}

}

//容器存储对象指针
void test03(){
	
	//创建栈
	LinkStack<Teacher*> lstack;
	//插入数据
	Teacher t1("aaa", 10), t2("bbb", 20), t3("ccc", 30);
	lstack.Push(&t1);
	lstack.Push(&t2);
	lstack.Push(&t3);
	//遍历打印
	while (lstack.getLength() > 0){
		Teacher* teahcer = lstack.Top();
		cout << "Name:" << teahcer->m_name << " Age:" << teahcer->m_age << endl;;
		lstack.Pop();
	}

}

int main(){

	//test01();
	//test02();
	test03();
	system("pause");
	return EXIT_SUCCESS;
}

# 队列类_链式存储设计与实现

//LinkQueue.hpp
#ifndef LINKQUEUE_HPP
#define LINKQUEUE_HPP

//结点结构
template<class T>
class LinkNode{
public:
	T data;
	LinkNode* next;
};

//队列类
template<class T>
class LinkQueue{
public:
	//初始化链式队列
	LinkQueue(){
		pFront = NULL;
		pBack = NULL;
		mLength = 0;
	}
	//获得队列长度
	int getLength(){
		return this->mLength;
	}
	//队列加入元素
	void Push(T data){
		
		//创建新的结点
		LinkNode<T>* newnode = new LinkNode<T>();
		newnode->data = data;
		newnode->next = NULL;

		//判断是不是第一次插入
		if (pFront == NULL && pBack == NULL){
			pFront = newnode;
			pBack = newnode;
			this->mLength++;
			return;
		}

		//其他情况
		this->pBack->next = newnode;
		this->pBack = newnode;
		this->mLength++;

		return;
	}

	T& Front(){
		return this->pFront->data;
	}

	void Pop(){

		if (this->mLength == 0){
			return;
		}

		//当队列中只有一个元素的时候
		if (this->mLength == 1){
			delete this->pFront;
			this->pFront = NULL;
			this->pBack = NULL;
			this->mLength--;
			return;
		}

		//其他情况
		LinkNode<T>* pDel = this->pFront;
		this->pFront = pDel->next;
		delete pDel;
		this->mLength--;
		return;
	}

private:
	LinkNode<T>* pFront; //队头
	LinkNode<T>* pBack; //队尾
	int mLength; //队列长度
};

#endif
//LinkQueueTest.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include"LinkQueue.hpp"
using namespace std;

//存储基础数据类型
void test01(){

	//创建链式队列
	LinkQueue<int> queue;
	//添加数据
	for (int i = 0; i < 10;i++){
		queue.Push(i);
	}
	//修改队头元素的值
	queue.Front() = 100;
	//打印队列
	while (queue.getLength() > 0){
		int val = queue.Front();
		cout << val << " ";
		queue.Pop();
	}
	cout << endl;
}

int main(){

	test01();

	system("pause");
	return EXIT_SUCCESS;
}

# 链表类_顺序存储设计与实现

//SqList.hpp
#ifndef SQLIST_HPP
#define SQLIST_HPP

//链表类
template<class T>
class SqList{
public:
	//构造函数,由用户指定容量
	SqList(int capacity){
		this->mCapacity = capacity;
		this->mLength = 0;
		this->mArray = new T[capacity];
	}
	//获得容量
	int getCapacity(){
		return this->mCapacity;
	}
	//获得链表长度
	int getLength(){
		return this->mLength;
	}
	//获得数组
	T* getArray(){
		return this->mArray;
	}
	//获得指定位置元素
	T Get(int pos){
		if (pos > this->mLength - 1){
			return -1;
		}
		return this->mArray[pos];
	}
	//链表中指定位置插入结点
	void Insert(int pos, T data){
		if (this->mLength >= this->mCapacity){
			return;
		}
		if (pos > this->mLength){
			pos = this->mLength - 1;
		}

		this->mArray[pos] = data;
		this->mLength++;
	}
	//删除指定位置结点
	void Delete(int pos){
		
		if (pos > this->mLength-1){
			return;
		}

		for (int i = pos; i < mLength;i++){
			this->mArray[i] = this->mArray[i + 1];
		}
		this->mLength--;
	}

	~SqList(){
		if (mArray != NULL){
			delete mArray;
		}
	}
private:
	int mCapacity;//容量
	int mLength;//长度
	T* mArray;
};

#endif
//SqListTest.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"SqList.hpp"
using namespace std;

void test01(){
	
	//创建栈
	SqList<int> list(20);
	//插入数据
	for (int i = 0; i < 20;i++){
		list.Insert(i,i+1);
	}
	//打印数据
	for (int i = 0; i < 20;i++){
		cout << list.Get(i) << " ";
	}
	cout << endl;
}

int main(){
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

# 栈类_顺序存储设计与实现

//SqStack.hpp
#ifndef SQSTACK_HPP
#define SQSTACK_HPP

//栈的顺序存储
template<class T>
class SqStack{
public:
	//构造函数
	SqStack(int capacity){
		this->mCapacity = capacity;
		this->mLength = 0;
		this->mArray = new T[capacity];
	}
	int getLength(){
		return this->mLength;
	}
	//压栈
	void Push(T data){
		
		if (this->mLength >= this->mCapacity){
			return;
		}

		this->mArray[this->mLength] = data;
		this->mLength++;

	}

	//出栈
	T Top(){
		return this->mArray[this->mLength - 1];
	}

	//弹出栈顶元素
	void Pop(){
		this->mLength--;
	}

	~SqStack(){
		if (this->mArray != NULL){
			delete this->mArray;
		}
	}
private:
	T* mArray;
	int mCapacity; //容量
	int mLength; //长度
};

#endif
//SqStackTest.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"SqStack.hpp"
using namespace std;

void test01(){
	
	//创建栈
	SqStack<int> stack(20);
	//压栈
	for (int i = 0; i < 20;i++){
		stack.Push(i);
	}
	//遍历
	while (stack.getLength() > 0){
		cout << stack.Top() << " ";
		stack.Pop();
	}
	cout << endl;

}

int main(){
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

# 队列类_顺序存储设计与实现

//SqQueue.hpp
#ifndef SQQUEUE_HPP
#define SQQUEUE_HPP

//队列的顺序存储
template<class T>
class SqQueue{
public:
	SqQueue(int capacity){
		this->mCapacity = capacity;
		this->mLength = 0;
		this->mArray = new T[capacity];
	}
	//获得队列长度
	int getLength(){
		return this->mLength;
	}

	//获得容量
	int getCapacity(){
		return this->mCapacity;
	}

	//入队操作
	void Push(T data){
		if (this->mLength >= this->mCapacity){
			return;
		}
		this->mArray[mLength] = data;
		this->mLength++;
	}

	//出队操作
	T Front(){
		return this->mArray[0];
	}

	//队头弹出元素
	void Pop(){
		for (int i = 0; i < mLength; i++){
			mArray[i] = mArray[i + 1];
		}
		this->mLength--;
	}
private:
	int mLength;
	T* mArray;
	int mCapacity;
};

#endif
//SqQueueTest.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"SqQueue.hpp"
using namespace std;

void test01(){
	
	//创建队列
	SqQueue<int> queue(20);
	//向队列中插入元素
	for (int i = 0; i < 20;i++){
		queue.Push(i);
	}
	//打印队列元素
	while (queue.getLength() > 0){
		cout << queue.Front() << " ";
		queue.Pop();
	}
	cout << endl;

}

int main(){
	test01();
	system("pause");
	return EXIT_SUCCESS;
}
编辑此页
#algorithm
数据结构与算法
网络基础

← 数据结构与算法 网络基础 →

Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式