算法入门第一篇

1、给定一组“无序”记录序列{25, 30, 11, 7, 22, 16, 18, 33, 40, 55},采用冒泡排序、堆排序、直接选择排序以及直接插入排序方法,将该序列排成非递减序列,完成以下问题:

         1)写出冒泡排序、堆排序、直接选择排序和直接插入排序方法的Java实现代码。

2)采用上述4种方法进行排序时,都要执行的两种基本操作是什么?

3)写出冒泡排序第二趟排序后的结果。

        4)画出采用堆排序方法第一次抽取堆顶元素后得到的最小堆。

        5)采用直接选择法排序时,第5次交换和选择后,未排序记录是什么?

        6)采用直接插入法排序把第6个记录16插入有序表时,为寻找插入位置,需要比较多少次?

  7)试比较上述4种排序算法的性能(时间复杂度)。

2、问题提出:公元前5世纪末,中国古代数学家张丘建在他的《算经》中提出了著名的 “百钱买百鸡问题”:鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁、母、雏各几何?即一百个铜钱买了一百只鸡,其中公鸡一只5钱、母鸡一只3钱,雏鸡一钱3只,问一百只鸡中公鸡、母鸡、雏鸡各多少? 算法的伪代码如下:

for x = 0 to 100

     for y = 0 to 100

       for z = 0 to 100

         if  (x+y+z=100)  and  (5*x + 3*y + z/3 = 100)  then

           System.out.println("  "+x+"  "+y+"  "+z)

         end if

实验要求:对上述算法做出改进以提高算法的效率,要求将算法的时间复杂性由Ο(n3)降为 Ο(n2),并将改进的算法编程实现。

3、硬件厂商XYZ公司宣称他们研制的微处理器的运行速度是其竞争对手ABC公司同类产品的1000倍。对于计算复杂性分别为,算法入门第一篇算法入门第一篇算法入门第一篇,的各类算法,若用ABC公司的计算机能在1小时内解决输入规模为算法入门第一篇的问题,则用XYZ公司的计算机在1小时内能解决多大输入规模的问题?

4、假设某算法在输入规模为n时的计算时间为算法入门第一篇。在某台计算机上,于t秒内实现并完成该算法。现有另一台计算机,其运行速度为第一台的128倍,那么在这台新机器上用同一算法在t秒内能解决多大输入规模的问题?

 

1)

int num[] = new int[] { 25, 30, 11, 7, 22, 16, 18, 33, 40, 55 };

int len = num.length;

// 冒泡排序

public void bubbleSort() {

for (int i = 1; i < len; i++) {// n-1趟

 

int temp;

for (int j = 0; j < len - i; j++) {

if (num[j] > num[j + 1]) {

temp = num[j];

num[j] = num[j + 1];

num[j + 1] = temp;

 

}

}

 

}

 

}

// 堆排序

int leng = num.length;

List<Object> list = new ArrayList<Object>();

public void heapSort() {

 

for(int j = 0; j < leng; j++) {

for (int i = len / 2 - 1 ; i >= 0; i--) {// 创建堆

siftSmall(i, len);

}

list.add(num[0]);

num = remove(num,0);

len--;

}

 

for (Object n : list) {

System.out.print(n + " ");

}

 

}

private static int[] remove(int[] arr, int num) {

        int[] tmp = new int[arr.length - 1];

        int idx = 0;

        boolean hasRemove = false;

        for (int i = 0; i < arr.length; i++) {

 

            if (!hasRemove && i == num) {

                hasRemove = true;

                continue;

            }

 

            tmp[idx++] = arr[i];

        }

 

        return tmp;

}

 

// 创建最小堆

public void siftSmall(int low, int high) {

 

int i = low;// 子树的根结点

int j = 2 * i + 1; // j为i结点的左孩子

int temp = num[i];

while (j < high) { // 沿着较小值孩子结点向下筛选

if (j < high - 1 && num[j] > num[j + 1]) {

j++;// 记录比较,j为左右孩子的较小者

}

if (temp > num[j]) {// 若父结点较大

num[i] = num[j];// 孩子结点中较小者上移

i = j;

j = 2 * i + 1;

} else {

j = high + 1;

}

}

num[i] = temp;

}

 

// 直接选择排序

public void selectSort() {

int temp;

for (int i = 0; i < len; i++) {// n-1趟

int min = i;

for (int j = i + 1; j < len; j++) {

if (num[j] < num[min]) {

min = j;

}

 

}

if (min != i) {

temp = num[i];

num[i] = num[min];

num[min] = temp;

}

}

}

 

// 直接插入排序

public void insertSort() {// 将比较后较大数放在后一位

for (int i = 1; i < len; i++) {

// 准备插入的数

int temp = num[i];

int j = i - 1;

for (; j >= 0 && temp < num[j]; j--) {

num[j + 1] = num[j];

 

}

num[j + 1] = temp;// 将数组后一位数赋值,插入排序

 

}

 

}

2)比较数值大小、元素交换

3) 11 25 30 7 22 16 18 33 40 55

4)

算法入门第一篇

   

5)16、18、33、40、55

6) 3次

7)冒泡排序O(n^2)、堆排序O(nlog2n)、直接选择排序O(n^2)、直接插入排序O(n^2)

 

2.

public void test() {

for (int x = 0; x <= 20; x++) {

for (int y = 0; y <= 33; y++) {

if (5 * x + 3 * y + (100 - x - y) / 3 == 100 && (100 - x - y) % 3 == 0) {

System.out.println(x + " " + y + " " + (100 - x - y) + " ");

 

}

}

}

 

}

 

实现代码运行效果如下图

 

算法入门第一篇

 

 

 

 

3.

时间复杂度为n时,输入规模1000n

时间复杂度为算法入门第一篇时,输入规模 ²√1000 ≈31.623

时间复杂度为算法入门第一篇时,输入规模10n

4.

某台机器t秒内完成算法的计算时间 算法入门第一篇
新机器t秒内完成算法的计算时间=128*3*2^n=2^7*3*2^n=3*2^(n+7)
T=T(n)=3*2^n

 n=log2(T/3)
设新机器输入规模为n1,则:
n1=log2(3*2^(n+7)/3)=n+7