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:  生成随机的不重复的测试数据
    //[email protected] 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;
}

三、海量数据排序实例

    //[email protected] 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;
    }

四、多路归并排序

//[email protected] 纯净的天空 && 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;
    }
}
时间: 2024-10-03 15:32:21

Dijkstra算法以及各种海量数据排序算法的相关文章

基本算法研究1-冒泡排序算法测试

基本算法研究1-冒泡排序算法测试 1.经典冒泡排序法基本原理 先看一个动态图,感觉比较形象: 冒泡排序(Bubble Sort)是一种简单的排序算法.默认是从小到大排序,即把最大的数据排在最后,相当于每次把最大数据像气泡一样浮到水面一样.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换. 基本步骤: 1.比较相邻的元素.如果第一个比第二个大,就交换他们两个.        2.对每一对相邻元素作同样的工作,从开始第一对

【JavaScript】【算法】JavaScript版排序算法

JavaScript版排序算法:冒泡排序.快速排序.插入排序.希尔排序(小数据时,希尔排序会比快排快哦) 1 //排序算法 2 window.onload = function(){ 3 var array = [0,1,2,44,4, 4 324,5,65,6,6, 5 34,4,5,6,2, 6 43,5,6,62,43, 7 5,1,4,51,56, 8 76,7,7,2,1, 9 45,4,6,7,8]; 10 //var array = [4,2,5,1,0,3]; 11 array

链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述

关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学习过算法的系统性的课程,现在还是处于不断摸索的阶段,好多算法题目根本就没有什么思路,导致自己对好多题目都很是头疼,就算是自己做过的一些算法的题目,再次遇到也还是不一定会做出来,他给出的建议就是,看懂别人的程序,然后自己去敲,一定会出错,然后调试,有错误接着调试,一直到没有错误为止,并且要时常的去复习

算法导论专题一--排序算法

排序算法作为许多程序的中间步骤,是计算机科学中的一个基本操作. 一.问题描述 排序算法输入的是n个数的一个序列<a1,a2…..an>,输出为输入的一个排列<a1’,…..an’>,满足a1’<a2’<….<an’ 简言之就是输入一个序列,输出的是这个数组元素从小到大排列的另一序列. 二.方法思想综述 从算法导论这本书上根据算法的复杂度可以将排序算法分为三种,,.,这两种方法都需要数据间的比较,而不需要. 其中有三种为选择,冒泡,插入. 选择排序:最直观,简单但是

算法导论专题一--排序算法(2)

上节分析了O(n^2)的算法,这节就分析O(nlgn)的算法-归并,快速和堆排序. 一:综述 O(nlgn) 的算法可以分为两大类,两者所用的技术差别较大.归并和快速排序采用的是分治策略,这两者相当于一个对称的过程,一个是自顶向上合并子问题,另一个则自上向下分解子问题.而堆排序利用堆这一数据结构元素间的特殊关系来排序一个序列,另外采用二叉树的方式组织数据使其效率大大提高. 二:分治策略排序算法 1.为什么使用分治? 在上节算法的分析中,不管是冒泡.选择还是插入都不适用于大规模的数据,因为数据一大

冒泡排序算法和简单选择排序算法的js实现

之前已经介绍过冒泡排序算法和简单选择排序算法和原理,现在有Js实现. 冒泡排序算法 let dat=[5, 8, 10, 3, 2, 18, 17, 9]; function bubbleSort(data) { for(let i=0;i<data.length-1;i++){ for(let j=0;j<data.length-1-i;j++){ if(data[j]>data[j+1]){ [data[j],data[j+1]]=[data[j+1],data[j]]; } } }

python数据结构与算法第八天【排序算法】

1.排序算法的稳定性 稳定排序算法会让原本有相同键值的记录维持相对次序 例如:对以下元组按照元组的第一个元素升序排列,元组如下: (4,1) (3,1) (3,7) (5,6) 若要满足条件,则可能的排序有: 情况一: (3,1) (3,7) (4,1) (5,6) 情况二: (3,7) (3,1) (4,1) (5,6) 虽然情况一和情况二都是满足条件的,但是情况二在满足条件下打破了原本无需改变的顺序 原文地址:https://www.cnblogs.com/liuzhiqaingxyz/p/

数据结构与算法系列十(排序算法概述)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗? 于是问题来了:为什么还要学习数据结构与算法呢? #理由一: 面试的时候,千万不要被数据结构与算法拖了后腿 #理由二: 你真的愿意做一辈子CRUD Boy吗 #理由三: 不想写出开源框架,中间件的工程师,不是好厨子 1.2.如何系统化学习数据结构与算法?

深入理解排序算法(一):初级排序算法

[本系列博文会对常见的排序算法进行分析与总结,并会在最后提供几道相关的一线互联网企业面试/笔试题来巩固所学及帮助我们查漏补缺.项目地址:https://github.com/absfree/Algo.由于个人水平有限,叙述中难免存在不清晰准确的地方,希望大家可以指正,谢谢大家:)] 一.概述 我们在日常开发中经常需要对一组数据对象进行排序,这里的数据对象不仅包括数字,还可能是字符串等抽象数据类型(Abstract Data Type).由于排序是很多其他操作(比如二分查找)能够高效进行的基础,因