《啊哈,算法》阅读笔记

第一章:排序 13

第 1 节 最快最简单的排序——桶排序

简化版的桶排序
代码如下:

int[] book = new int[1001];
int i, j, t;
for (i = 0; i <= 1000; i++)
{
    book[i] = 0;
}

int n = int.Parse(Console.ReadLine());//输入一个数n,表示接下来有n个数
for (i = 1; i <= n; i++)//循环读入n个数,并进行桶排序
{
    t = int.Parse(Console.ReadLine()); //把每一个数读到变量t中
    book[t]++; //进行计数,对编号为t的桶放一个小旗子
}
for (i = 1000; i >= 0; i--) //依次判断编号1000~0的桶
{
    if (book[i] == 1)
    {
        Console.WriteLine("{0}", i); 
    }
}

我要说原理:有一千个桶,你输入1,就给序号1的标记,你输入10就给输入10的标记;
输出的时候,只对标记的输出;输出的自带顺序,因为再输入的时候已经按序入桶了。
问题是:
你输入的数字不能大于桶的个数,否则没地方安置你;
输入的数字还不能重复,否则会被替换掉,只能保留一个。
你输入的数字也不能说复数,因为,序号没有负数;
结论:这是一个弊端很多,但是很好玩的算法;
算法复杂度(m是桶的个数,n为待排序个数):O(m+n+m+n);忽略较小常数O(M+N)

第二节:冒泡排序

冒泡排序的基本思想是:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换
过来。既然是从大到小排序,也就是说越小的越靠后。
冒泡排序
代码如下

int[] a = new int[100];
    int i, j, t;
int n = int.Parse(Console.ReadLine());//输入一个数n,表示接下来有n个数 //输入一个数n,表示接下来有n个数
for (i = 1; i <= n; i++) //循环读入n个数到数组a中
{
    a[i] = int.Parse(Console.ReadLine());//输入一个数n,表示接下来有n个数
}
//冒泡排序的核心部分
for (i = 1; i <= n - 1; i++) //n个数排序,只用进行n-1趟
{
    for (j = 1; j <= n - i; j++) //从第1位开始比较直到最后一个尚未归位的数

    {
        if (a[j] < a[j + 1]) //比较大小并交换
        { t = a[j]; a[j] = a[j + 1]; a[j + 1] = t; }
    }
}
for (i = 1; i <= n; i++) //输出结果
{
    Console.WriteLine(":{0} ", a[i]);
}

冒泡排序的核心部分是双重嵌套循环。不难看出冒泡排序的时间复杂度是 O(N 2
)。

第三节: 快速排序

首先,从数组中选择一个元素,这个元素被称为基准值(pivot)。
我们暂时将数组的第一个元素用作基准值。
接下来,找出比基准值小的元素以及比基准值大的元素。
一个由所有小于基准值的数字组成的子数组;
基准值;
一个由所有大于基准值的数组组成的子数组。
如果子数组是有序的,就可以像下面这样合并得到一个有序的数组:左边的数组 + 基准值 + 右边的数组。在这里,就是[10, 15] + [33] + [],结果为有序数组[10, 15, 33]。

static List<int> QuickSort(List<int> array)
    {
        if (array.Count < 2)
        {
            return array;
        }
        else
        {
            int pivot = array[0];
            List<int> less = new List<int>();
            List<int> greater = new List<int>();

            for (int i = 1; i < array.Count; i++)
            {
                if (array[i] <= pivot)
                {
                    less.Add(array[i]);
                }
                else
                {
                    greater.Add(array[i]);
                }
            }

            List<int> sortedLess = QuickSort(less);
            List<int> sortedGreater = QuickSort(greater);

            sortedLess.Add(pivot);
            sortedLess.AddRange(sortedGreater);

            return sortedLess;
        }
    }

第二章:栈,队列,链表 37

第一节 队列

只允许队首出队(删除),队尾插入(新增);

struct queue 
{ 
 int data[100];//队列的主体,用来存储内容
 int head;//队首
 int tail;//队尾
};

队首和队尾重合则队列为空;队首和队尾记录的是他们的位置

第二节:栈

有一种是后进先出的数据结构,它叫做栈。栈限定为只能在一端进行插入和删除操作。

第四节:链表

每一个结点都由两个部分组成。左边的部分用来存放具体的数值,那么用一个整型变量
就可以;右边的部分需要存储下一个结点的地址,可以用指针来实现(也称为后继指针)。

struct node 
{ 
 int data; 
 struct node *next; 
};

第三章:枚举
枚举算法,又叫群举算法;
有序地去尝试每一种可能;

剩下的还没读呢,等读到了再分享。

你可能感兴趣的:(算法,笔记)