Dijkstra算法以及各种海量数据排序算法
一、Dijkstra最短路径算法
是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
实现一
//
// Dijkstra
// ACM
// Find the number of minimal path
//
// Created by Rachel on 18-2-12.
// Copyright (c) 2014年 ZJU. All rights reserved.
// #include <iostream>
#include <algorithm>
#include <stdio.h>
#include <functional>
#include <utility>
#include <memory.h>
using namespace std;
#define N 505
#define INF 100000000
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b int map[N][N];
int minres[N]; //min distance from source to point_i
bool visited[N];
int weight[N]; void init(int n)
{
int i,j;
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
map[i][j] = INF;
}
minres[i] = INF;
}
memset(visited, false, sizeof(visited));
} void dijkstra(int source, int dest, int n)
{
int i,j;
for(i=0;i<n;i++)
minres[i]=map[source][i];
visited[source]=true; // (n-1) times, each time select one point into the start point set
for (j=0; j<n-1; j++) {
//select a point to add into the start point set
int minn = INF, point=-1;
for(i=0;i<n;i++)
if (!visited[i]&&minres[i]<minn) {
minn = minres[i];
point = i;
}
visited[point] = true; //update the min distance of other points
for (i=0; i<n; i++) {
if (!visited[i]&&minres[i]>minres[point]+map[point][i]) {
minres[i] = minres[point]+map[point][i];
}
}
}
} void dfs(int source, int dest,int n, int curpoint, int curdis, int cursum, int* num, int* sum)
{
if (curpoint==dest && minres[dest]==curdis) {
*num = *num+1;
*sum = max(*sum, cursum);
return;
}
if (curdis>minres[dest])
return;
for (int i=0; i<n; i++) {
if(!visited[i]&&map[curpoint][i]!=INF)
{
visited[i] = true;
dfs(source, dest, n, i, curdis+map[curpoint][i], cursum+weight[i], num, sum);
visited[i] = false;
}
}
} int main()
{
int i,m,n,a,b,t,source,dest;
while (cin>>n>>m) {
cin>>source>>dest;
for (i=0; i<n; i++) {
cin>>weight[i]; //#peoples @ each point
}
init(n);
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&t);
map[b][a] = map[a][b]= min(map[a][b],t);
}
dijkstra(source,dest,n);
minres[source] = 0;
int num = 0, sum = 0;
memset(visited, false, sizeof(visited));
visited[source] = true;
dfs(source, dest, n, source, 0, weight[source], &num, &sum);
cout<<num<<" "<<sum<<endl;
}
}
实现二
/*Dijkstra求单源最短路径 2010.8.26*/
/*http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html
*/
#include <iostream>
#include<stack>
#define M 100
#define N 100
using namespace std; typedef struct node
{
int matrix[N][M]; //邻接矩阵
int n; //顶点数
int e; //边数
}MGraph; void DijkstraPath(MGraph g,int *dist,int *path,int v0) //v0表示源顶点
{
int i,j,k; bool *visited=(bool *)malloc(sizeof(bool)*g.n); for(i=0;i<g.n;i++) //初始化
{
if(g.matrix[v0][i]>0&&i!=v0)
{
dist[i]=g.matrix[v0][i];
path[i]=v0; //path记录最短路径上从v0到i的前一个顶点
}
else
{
dist[i]=INT_MAX; //若i不与v0直接相邻,则权值置为无穷大
path[i]=-1;
}
visited[i]=false;
path[v0]=v0;
dist[v0]=0;
}
visited[v0]=true;
for(i=1;i<g.n;i++) //循环扩展n-1次
{
int min=INT_MAX;
int u;
for(j=0;j<g.n;j++) //寻找未被扩展的权值最小的顶点
{
if(visited[j]==false&&dist[j]<min)
{
min=dist[j];
u=j;
}
}
visited[u]=true;
for(k=0;k<g.n;k++) //更新dist数组的值和路径的值
{
if(visited[k]==false&&g.matrix[u][k]>0&&min+g.matrix[u][k]<dist[k])
{
dist[k]=min+g.matrix[u][k];
path[k]=u;
}
}
}
} void showPath(int *path,int v,int v0) //打印最短路径上的各个顶点
{
stack<int> s;
int u=v;
while(v!=v0)
{
s.push(v);
v=path[v];
}
s.push(v);
while(!s.empty())
{
cout<<s.top()<<" ";
s.pop();
}
} int main(int argc, char *argv[])
{
int n,e; //表示输入的顶点数和边数
while(cin>>n>>e&&e!=0)
{
int i,j;
int s,t,w; //表示存在一条边s->t,权值为w
MGraph g;
int v0;
int *dist=(int *)malloc(sizeof(int)*n);
int *path=(int *)malloc(sizeof(int)*n); for(i=0;i<N;i++)
for(j=0;j<M;j++)
g.matrix[i][j]=0;
g.n=n;
g.e=e;
for(i=0;i<e;i++)
{
cin>>s>>t>>w;
g.matrix[s][t]=w;
}
cin>>v0; //输入源顶点
DijkstraPath(g,dist,path,v0);
for(i=0;i<n;i++)
{
if(i!=v0)
{
showPath(path,i,v0);
cout<<dist[i]<<endl;
}
}
}
return 0;
}
二、基于bitset排序
各种排序算法,生成随机文件程序。
//purpose: 生成随机的不重复的测试数据
//copyright@ 2011.04.19 yansha
//1000w数据量,要保证生成不重复的数据量,一般的程序没有做到。
//但,本程序做到了。
//July、2010.05.30。
#include <iostream>
#include <time.h>
#include <assert.h>
using namespace std; const int size = 10000000;
int num[size]; int main()
{
int n;
FILE *fp = fopen("data.txt", "w");
assert(fp); for (n = 1; n <= size; n++)
//之前此处写成了n=0;n<size。导致下面有一段小程序的测试数据出现了0,特此订正。
num[n] = n;
srand((unsigned)time(NULL));
int i, j; for (n = 0; n < size; n++)
{
i = (rand() * RAND_MAX + rand()) % 10000000;
j = (rand() * RAND_MAX + rand()) % 10000000;
swap(num[i], num[j]);
} for (n = 0; n < size; n++)
fprintf(fp, "%d ", num[n]);
fclose(fp);
return 0;
}
基于bitset实现方法
#include<iostream>
#include<bitset>
#include<assert.h>
#include<time.h>
using namespace std; const int max_each_scan=5000000; int main(){
clock_t begin=clock(); bitset<max_each_scan> bitmap;
bitmap.reset(); FILE* fp_unsort_file=fopen("data.txt","r");
assert(fp_unsort_file);
int num; while(fscanf(fp_unsort_file,"%d",&num)!=EOF){
if(num<max_each_scan)
bitmap.set(num,1);
} FILE* fp_sort_file=fopen("sort.txt","w");
assert(fp_sort_file);
int i ; for(i=0;i<max_each_scan;i++){
if(bitmap[i]==1)
fprintf(fp_sort_file, "%d\n", i);
}
int result=fseek(fp_unsort_file,0,SEEK_SET);
if(result)
cout<<"failed"
else{
bitmap.reset();
while(fscanf(fp_unsort_file,"%d",$num)!=EOF){
if(num>max_each_scan&&num<10000000){
num=num-max_ean_scan;
bitmap.set(num,1);
}
}
for(i=0;i<max_each_scan;i++){
if(bitmap[i]==1){
fprintf(fp_sort_file, "%d\n", max_each_scan+i);
}
}
} clock_t end=clock();
cout<<"排序用时:"<<endl;
cout << (end - begin) / CLK_TCK << "s" << endl;
fclose(fp_sort_file);
fclose(fp_unsort_file);
return 0;
}
三、海量数据排序实例
//copyright@ yansha
//July、updated,2011.05.28。
#include <iostream>
#include <string>
#include <algorithm>
#include <time.h>
using namespace std; int sort_num = 10000000;
int memory_size = 250000; //每次只对250k个小数据量进行排序
int read_data(FILE *fp, int *space)
{
int index = 0;
while (index < memory_size && fscanf(fp, "%d ", &space[index]) != EOF)
index++;
return index;
} void write_data(FILE *fp, int *space, int num)
{
int index = 0;
while (index < num)
{
fprintf(fp, "%d ", space[index]);
index++;
}
} // check the file pointer whether valid or not.
void check_fp(FILE *fp)
{
if (fp == NULL)
{
cout << "The file pointer is invalid!" << endl;
exit(1);
}
} int compare(const void *first_num, const void *second_num)
{
return *(int *)first_num - *(int *)second_num;
} string new_file_name(int n)
{
char file_name[20];
sprintf(file_name, "data%d.txt", n);
return file_name;
} int memory_sort()
{
// open the target file.
FILE *fp_in_file = fopen("data.txt", "r");
check_fp(fp_in_file);
int counter = 0;
while (true)
{
// allocate space to store data read from file.
int *space = new int[memory_size];
int num = read_data(fp_in_file, space);
// the memory sort have finished if not numbers any more.
if (num == 0)
break; // quick sort.
qsort(space, num, sizeof(int), compare);
// create a new auxiliary file name.
string file_name = new_file_name(++counter);
FILE *fp_aux_file = fopen(file_name.c_str(), "w");
check_fp(fp_aux_file); // write the orderly numbers into auxiliary file.
write_data(fp_aux_file, space, num);
fclose(fp_aux_file);
delete []space;
}
fclose(fp_in_file); // return the number of auxiliary files.
return counter;
} void merge_sort(int file_num)
{
if (file_num <= 0)
return;
// create a new file to store result.
FILE *fp_out_file = fopen("result.txt", "w");
check_fp(fp_out_file); // allocate a array to store the file pointer.
FILE **fp_array = new FILE *[file_num];
int i;
for (i = 0; i < file_num; i++)
{
string file_name = new_file_name(i + 1);
fp_array[i] = fopen(file_name.c_str(), "r");
check_fp(fp_array[i]);
} int *first_data = new int[file_num];
//new出个大小为0.1亿/250k数组,由指针first_data指示数组首地址
bool *finish = new bool[file_num];
memset(finish, false, sizeof(bool) * file_num); // read the first number of every auxiliary file.
for (i = 0; i < file_num; i++)
fscanf(fp_array[i], "%d ", &first_data[i]);
while (true)
{
int index = 0;
while (index < file_num && finish[index])
index++; // the finish condition of the merge sort.
if (index >= file_num)
break;
//主要的修改在上面两行代码,就是merge sort结束条件。
//要保证所有文件都读完,必须使得finish[0]...finish[40]都为真
//July、yansha,555,2011.05.29。 int min_data = first_data[index];
// choose the relative minimum in the array of first_data.
for (i = index + 1; i < file_num; i++)
{
if (min_data > first_data[i] && !finish[i])
//一旦发现比min_data更小的数据first_data[i]
{
min_data = first_data[i];
//则置min_data<-first_data[i]index = i;
//把下标i 赋给index。
}
} // write the orderly result to file.
fprintf(fp_out_file, "%d ", min_data);
if (fscanf(fp_array[index], "%d ", &first_data[index]) == EOF)
finish[index] = true;
} fclose(fp_out_file);
delete []finish;
delete []first_data;
for (i = 0; i < file_num; i++)
fclose(fp_array[i]);
delete [] fp_array;
} int main()
{
clock_t start_memory_sort = clock();
int aux_file_num = memory_sort();
clock_t end_memory_sort = clock();
cout << "The time needs in memory sort: " << end_memory_sort - start_memory_sort << endl;
clock_t start_merge_sort = clock();
merge_sort(aux_file_num);
clock_t end_merge_sort = clock();
cout << "The time needs in merge sort: " << end_merge_sort - start_merge_sort << endl;
system("pause");
return 0;
}
四、多路归并排序
//copyright@ 纯净的天空 && yansha
//5、July,updated,2010.05.28。
//harryshayne,update again。2011.6.30
#include <iostream>
#include <ctime>
#include <fstream>
//#include "ExternSort.h"
using namespace std; //使用多路归并进行外排序的类
//ExternSort.h /*
* 大数据量的排序
* 多路归并排序
* 以千万级整数从小到大排序为例
* 一个比较简单的例子,没有建立内存缓冲区
*/ #ifndef EXTERN_SORT_H
#define EXTERN_SORT_H #include <cassert>
//#define k 5
#define MIN -1//这里开始的时候出现了一个BUG,如果定义的MIN大于等于待排序的数,则会是算法出现错误
#define MAX 10000000//最大值,附加在归并文件结尾
typedef int* LoserTree;
typedef int* External; class ExternSort
{
public:
void sort()
{
time_t start = time(NULL); //将文件内容分块在内存中排序,并分别写入临时文件
k = memory_sort(); // //归并临时文件内容到输出文件
//merge_sort(file_count);
ls=new int[k];
b=new int[k+1]; K_Merge();
delete []ls;
delete []b; time_t end = time(NULL);
printf("total time:%f\n", (end - start) * 1000.0/ CLOCKS_PER_SEC);
} //input_file:输入文件名
//out_file:输出文件名
//count: 每次在内存中排序的整数个数
ExternSort(const char *input_file, const char * out_file, int count)
{
m_count = count;
m_in_file = new char[strlen(input_file) + 1];
strcpy(m_in_file, input_file);
m_out_file = new char[strlen(out_file) + 1];
strcpy(m_out_file, out_file);
}
virtual ~ExternSort()
{
delete [] m_in_file;
delete [] m_out_file;
} private:
int m_count; //数组长度
char *m_in_file; //输入文件的路径
char *m_out_file; //输出文件的路径 int k;//归并数,此数必须要内排序之后才能得到,所以下面的ls和b都只能定义为指针(注意和书上区别) LoserTree ls;//定义成为指针,之后动态生成数组
External b;//定义成为指针,在成员函数中可以把它当成数组使用
//int External[k];
protected:
int read_data(FILE* f, int a[], int n)
{
int i = 0;
while(i < n && (fscanf(f, "%d", &a[i]) != EOF)) i++;
printf("read:%d integer\n", i);
return i;
}
void write_data(FILE* f, int a[], int n)
{
for(int i = 0; i < n; ++i)
fprintf(f, "%d ", a[i]);
fprintf(f,"%d",MAX);//在最后写上一个最大值
}
char* temp_filename(int index)
{
char *tempfile = new char[100];
sprintf(tempfile, "temp%d.txt", index);
return tempfile;
}
static int cmp_int(const void *a, const void *b)
{
return *(int*)a - *(int*)b;
} int memory_sort()
{
FILE* fin = fopen(m_in_file, "rt");
int n = 0, file_count = 0;
int *array = new int[m_count]; //每读入m_count个整数就在内存中做一次排序,并写入临时文件
while(( n = read_data(fin, array, m_count)) > 0)
{
qsort(array, n, sizeof(int), cmp_int);
//这里,调用了库函数阿,在第四节的c实现里,不再调用qsort。
char *fileName = temp_filename(file_count++);
FILE *tempFile = fopen(fileName, "w");
free(fileName);
write_data(tempFile, array, n);
fclose(tempFile);
} delete [] array;
fclose(fin); return file_count;
} void Adjust(int s)
{//沿从叶子节点b[s]到根节点ls[0]的路径调整败者树
int t=(s+k)/2;//ls[t]是b[s]的双亲节点 while(t>0)
{
if(b[s]>b[ls[t]])//如果失败,则失败者位置s留下,s指向新的胜利者
{
int tmp=s;
s=ls[t];
ls[t]=tmp;
}
t=t/2;
}
ls[0]=s;//ls[0]存放调整后的最大值的位置
} void CreateLoserTree()
{
b[k]=MIN;//额外的存储一个最小值
for(int i=0;i<k;i++)ls[i]=k;//先初始化为指向最小值,这样后面的调整才是正确的
//这样能保证非叶子节点都是子树中的“二把手”
for(i=k-1;i>=0;i--)
Adjust(i);//依次从b[k-1],b[k-2]...b[0]出发调整败者树
} void K_Merge()
{//利用败者数把k个输入归并段归并到输出段中
//b中前k个变量存放k个输入段中当前记录的元素
//归并临时文件
FILE *fout = fopen(m_out_file, "wt");
FILE* *farray = new FILE*[k];
int i;
for(i = 0; i < k; ++i) //打开所有k路输入文件
{
char* fileName = temp_filename(i);
farray[i] = fopen(fileName, "rt");
free(fileName);
} for(i = 0; i < k; ++i) //初始读取
{
if(fscanf(farray[i], "%d", &b[i]) == EOF)//读每个文件的第一个数到data数组
{
printf("there is no %d file to merge!",k);
return;
}
}
// for(int i=0;i<k;i++)input(b[i]); CreateLoserTree();
int q;
while(b[ls[0]]!=MAX)//
{
q=ls[0];//q用来存储b中最小值的位置,同时也对应一路文件
//output(q);
fprintf(fout,"%d ",b[q]);
//input(b[q],q);
fscanf(farray[q],"%d",&b[q]);
Adjust(q);
}
//output(ls[0]);
fprintf(fout,"%d ",b[ls[0]]);
//delete [] hasNext;
//delete [] data; for(i = 0; i < k; ++i) //清理工作
{
fclose(farray[i]);
}
delete [] farray;
fclose(fout);
}
/*
void merge_sort(int file_count)
{
if(file_count <= 0) return; //归并临时文件
FILE *fout = fopen(m_out_file, "wt");
FILE* *farray = new FILE*[file_count];
int i;
for(i = 0; i < file_count; ++i)
{
char* fileName = temp_filename(i);
farray[i] = fopen(fileName, "rt");
free(fileName);
} int *data = new int[file_count];//存储每个文件当前的一个数字
bool *hasNext = new bool[file_count];//标记文件是否读完
memset(data, 0, sizeof(int) * file_count);
memset(hasNext, 1, sizeof(bool) * file_count); for(i = 0; i < file_count; ++i) //初始读取
{
if(fscanf(farray[i], "%d", &data[i]) == EOF)//读每个文件的第一个数到data数组
hasNext[i] = false;
} while(true) //循环读取和输出,选择最小数的方法是简单遍历选择法
{
//求data中可用的最小的数字,并记录对应文件的索引
int min = data[0];
int j = 0; while (j < file_count && !hasNext[j]) //顺序跳过已读取完毕的文件
j++; if (j >= file_count) //没有可取的数字,终止归并
break; for(i = j +1; i < file_count; ++i) //选择最小数,这里应该是i=j吧!但结果是一样的!
{
if(hasNext[i] && min > data[i])
{
min = data[i];
j = i;
}
} if(fscanf(farray[j], "%d", &data[j]) == EOF) //读取文件的下一个元素
hasNext[j] = false;
fprintf(fout, "%d ", min); } delete [] hasNext;
delete [] data; for(i = 0; i < file_count; ++i)
{
fclose(farray[i]);
}
delete [] farray;
fclose(fout);
}
*/
}; #endif //测试主函数文件
/*
* 大文件排序
* 数据不能一次性全部装入内存
* 排序文件里有多个整数,整数之间用空格隔开
*/ const unsigned int count = 10000000; // 文件里数据的行数
const unsigned int number_to_sort = 100000; //在内存中一次排序的数量
const char *unsort_file = "unsort_data.txt"; //原始未排序的文件名
const char *sort_file = "sort_data.txt"; //已排序的文件名
void init_data(unsigned int num); //随机生成数据文件 int main(int argc, char* *argv)
{
srand(time(NULL));
init_data(count);
ExternSort extSort(unsort_file, sort_file, number_to_sort);
extSort.sort();
system("pause");
return 0;
} void init_data(unsigned int num)
{
FILE* f = fopen(unsort_file, "wt");
for(int i = 0; i < num; ++i)
fprintf(f, "%d ", rand());
fclose(f);
}
五、字符串回文结构判断
class Solution{
//http://blog.csdn.net/v_july_v/article/details/6712171
public:
/**
*check weather s is a palindrome, n is the length of string s
*Copyright(C) fairywell 2011
*/
bool IsPalindrome(const char *s, int n)
{
if (s == 0 || n < 1) return false; // invalid string
char *front, *back;
front = s; back = s + n - 1; // set front and back to the begin and endof the string
while (front < back) {
if (*front != *back) return false; // not a palindrome
++front; --back;
}
return true; // check over, it's a palindrome } /**
*check weather s is a palindrome, n is the length of string s
*Copyright(C) fairywell 2011
*/
bool IsPalindrome2(const char *s, int n)
{
if (s == 0 || n < 1) return false; // invalid string
char *first, *second;
int m = ((n>>1) - 1) >= 0 ? (n>>1) - 1 : 0; // m is themiddle point of s
first = s + m; second = s + n - 1 - m;
while (first >= s)
if (s[first--] !=s[second++]) return false; // not equal, so it's not apalindrome
return true; // check over, it's a palindrome
}
/**
*find the longest palindrome in a string, n is the length of string s
*Copyright(C) fairywell 2011
*/
int LongestPalindrome(const char *s, int n)
{
int i, j, max;
if (s == 0 || n < 1) return 0;
max = 0; for (i = 0; i < n; ++i) { // i is the middle point of the palindrome
for (j = 0; (i-j >= 0) && (i+j < n); ++j) // if the lengthof the palindrome is odd
if (s[i-j] != s[i+j]) break; if (j*2+1 > max) max = j * 2 + 1; for (j = 0; (i-j >= 0) && (i+j+1 < n); ++j) // for theeven case
if (s[i-j] != s[i+j+1]) break; if (j*2+2 > max) max = j * 2 + 2;
}
return max;
} int LongestPalindrome(const char *s, int n)
{
int max = 0;
int i,j;
for ( i = 0; i < n ; i++ )
{//以i为中心开始计算回文子串
//计算奇数回问子串长度
for ( j = 0; (i-j) >= 0 && (i+j) < n; j++ )
{
if ( s[i-j] != s[i+j] )
{
break;
}
else
{
max = GETMAX(max, (2 * j + 1));
}
} //计算偶数回问子串长度
for ( j = 0; (i-j) >= 0 && i + j + 1< n; j++ )
{
if ( s[i-j] != s[i+j+1])
{
break;
}
else
{
max = GETMAX(max, ( 2 * j + 2) );
}
}
} return max;
}
}
Dijkstra算法以及各种海量数据排序算法的更多相关文章
- 数据结构和算法(Golang实现)(25)排序算法-快速排序
快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊. 注:A ...
- 链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述
关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学 ...
- 冒泡排序算法和简单选择排序算法的js实现
之前已经介绍过冒泡排序算法和简单选择排序算法和原理,现在有Js实现. 冒泡排序算法 let dat=[5, 8, 10, 3, 2, 18, 17, 9]; function bubbleSort(d ...
- 数据结构和算法(Golang实现)(18)排序算法-前言
排序算法 人类的发展中,我们学会了计数,比如知道小明今天打猎的兔子的数量是多少.另外一方面,我们也需要判断,今天哪个人打猎打得多,我们需要比较. 所以,排序这个很自然的需求就出来了.比如小明打了5只兔 ...
- 数据结构和算法(Golang实现)(19)排序算法-冒泡排序
冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 ...
- 数据结构和算法(Golang实现)(20)排序算法-选择排序
选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟 ...
- 数据结构和算法(Golang实现)(21)排序算法-插入排序
插入排序 插入排序,一般我们指的是简单插入排序,也可以叫直接插入排序.就是说,每次把一个数插到已经排好序的数列里面形成新的排好序的数列,以此反复. 插入排序属于插入类排序算法. 除了我以外,有些人打扑 ...
- 数据结构和算法(Golang实现)(22)排序算法-希尔排序
希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机 ...
- 数据结构和算法(Golang实现)(23)排序算法-归并排序
归并排序 归并排序是一种分治策略的排序算法.它是一种比较特殊的排序算法,通过递归地先使每个子序列有序,再将两个有序的序列进行合并成一个有序的序列. 归并排序首先由著名的现代计算机之父John_von_ ...
随机推荐
- 设计模式23:Visitor 访问者模式(行为型模式)
Visitor 访问者模式(行为型模式) 动机(Motivation)在软件构造过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的修改,将会给子类带来繁重的 ...
- AC620教程 第十五节 8位7段数码管驱动设计与验证
本章导读 电子系统中常用的显示设备有数码管.LCD液晶以及VGA显示器等.其中数码管又可分为段式显示(7段.米字型等)以及点阵显示(8*8.16*16等),LCD液晶的应用可以分为字符式液晶(1602 ...
- APUE(5)---标准I/O库 (2)
六.读和写流 一旦打开了流,则可在3种不同类型的非格式化I/O中进行选择,对其进行读.写操作:1)每次一个字符的I/O,一次读或写一个字符,如果刘时代缓冲的,则标准I/O函数处理所有缓冲:2)每次一行 ...
- Javascript与数据结构系列(一)——栈的实现
栈的实现 实现一个栈,当务之急是决定存储数据的底层数据结构.这里采用的是数组. 我们的实现以定义 Stack 类的构造函数开始: function Stack() { this.dataStore = ...
- Jquery ajax的参数格式化
jQuery的ajax会自动将js对象转换为可传递的参数,$.param(jsobj, boolean),但是默认会把对象中数组类型加上[]符号,后台就不怎么好取了 参数boolean为true时不加 ...
- [leetcode] 4. Path Sum
终于到了二叉树.题目如下: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that ...
- VS2010下安装OpenCV2.4.3
本文记录Windows 7 X86 SP1操作系统环境下,安装与配置OpenCV2.4.3的详细步骤.前置需求:已安装有VS2010. 下载并安装OpenCV 从http://www.opencv.o ...
- C#中使用Redis学习二 在.NET4.5中使用redis hash操作
上一篇>> 摘要 上一篇讲述了安装redis客户端和服务器端,也大体地介绍了一下redis.本篇着重讲解.NET4.0 和 .NET4.5中如何使用redis和C# redis操作哈希表. ...
- C# Winform 使用Application.Exit重新启动应用程序example
Application.Exit会在所有前台线程退出后,退出应用, Environment.Exit则立即终止进程,相比之下Environment.Exit更狠些 private static voi ...
- Word页面去除下划线(Office 2017)实现
后面就不用说了吧设置边框无