作业:递归实现插入排序和在o(nlgn)时间复杂度内寻找和为定值的两个元素
2007-09-13 08:11
776 查看
1、递归实现插入排序
基本思想:
可以把插入排序看作递归 地排序A[1..n-1]然后插入a
到已经排好序的序列a[1..n-1]中。
一下是实现算法(C#描述,VS205中调试通过)
class InsertSort
...{
static void Main(string[] args)
...{ int[] array1=...{15,1,2333,4,5,67,24,645,253,8,9,34,22,100,22,23,45,67};
ISort(array1, array1.Length);
for (int i = 0; i < array1.Length; i++)
...{
Console.WriteLine(array1[i]);
}
Console.Read();
}
//递归实现插入排序
static void ISort(int[] a,int n)
...{
if (n > 2)
ISort(a, n - 1);
InsertToArray(a[n - 1], a, n - 2);
}
private static void InsertToArray(int data, int[] a, int last)
...{
while (last>=0 && data < a[last])
...{
a[last + 1] = a[last];
last--;
}
a[last + 1] = data;
}
}
2、描述一个时间复杂度为o(nlgn)的算法找到在集合S中和为x的两个元素
基本思想:对集合s进行排序,时间复杂度为o(nlgn)的排序算法有快速排序,堆排序和归并排序。然后对已经排好序的序列进行一遍扫描找到两个元素。使得整个算法的时间复杂度为O(nlogn)。
实现算法(C#描述,VS205中调试通过,采用快速排序)
class ElementsInS
...{
static void Main(string[] args)
...{
Console.WriteLine("请输入数组S中的元素,以","分开");//输入数组S
string s =Console.ReadLine(); //生成数组S
string[] a = s.Split(',');
List<int> ls = new List<int>() ;
foreach(string t in a)
...{
int i;
if(int.TryParse(t,out i))
ls.Add(i);
}
Console.WriteLine("请输入数字S:");
int x =int.Parse(Console.ReadLine()); //输入和x
int[] aa = new int[ls.Count]; //从List copy数组s
ls.CopyTo(aa,0);
myQuickSort(aa, 0, ls.Count-1); //先对其进行快速排序时间复杂度为O(nlgn)
//以下循环一遍寻找两个元素
int f = 0;
int l = aa.Length-1;
while(f<l)
...{
if(aa[f]+aa[l] == x)
...{
Console.WriteLine("已经找到S的俩元素:" + aa[f].ToString() + "和" + aa[l].ToString());
break; //找到元素
}
else if(aa[f]+aa[l]>x) //两数和大数已知数时,移动尾游标
--l;
else //两数和小于已知数时, 移动头游标
++f;
}
if (f >= l)
...{
Console.WriteLine("数组s中没有和为" + x.ToString() + "的俩元素");
}
Console.ReadLine();
}
//以下为快速排序
private static void Swap(ref int i, ref int j)
//swap two integer
...{
int t;
t = i;
i = j;
j = t;
}
public static void Sort(int[] list, int low, int high)
...{
if (high <= low)
...{
//only one element in array list
//so it do not need sort
return;
}
else if (high == low + 1)
...{
//means two elements in array list
//so we just compare them
if (list[low] > list[high])
...{
//exchange them
Swap(ref list[low], ref list[high]);
return;
}
}
//more than 3 elements in the arrary list
//begin QuickSort
myQuickSort(list, low, high);
}
public static void myQuickSort(int[] list, int low, int high)
...{
if (low < high)
...{
int pivot = Partition(list, low, high);
myQuickSort(list, low, pivot - 1);
myQuickSort(list, pivot + 1, high);
}
}
private static int Partition(int[] list, int low, int high)
...{
//get the pivot of the arrary list
int pivot;
pivot = list[low];
while (low < high)
...{
while (low < high && list[high] >= pivot)
...{
high--;
}
if (low != high)
...{
Swap(ref list[low], ref list[high]);
low++;
}
while (low < high && list[low] <= pivot)
...{
low++;
}
if (low != high)
...{
Swap(ref list[low], ref list[high]);
high--;
}
}
return low;
}
}
基本思想:
可以把插入排序看作递归 地排序A[1..n-1]然后插入a
到已经排好序的序列a[1..n-1]中。
一下是实现算法(C#描述,VS205中调试通过)
class InsertSort
...{
static void Main(string[] args)
...{ int[] array1=...{15,1,2333,4,5,67,24,645,253,8,9,34,22,100,22,23,45,67};
ISort(array1, array1.Length);
for (int i = 0; i < array1.Length; i++)
...{
Console.WriteLine(array1[i]);
}
Console.Read();
}
//递归实现插入排序
static void ISort(int[] a,int n)
...{
if (n > 2)
ISort(a, n - 1);
InsertToArray(a[n - 1], a, n - 2);
}
private static void InsertToArray(int data, int[] a, int last)
...{
while (last>=0 && data < a[last])
...{
a[last + 1] = a[last];
last--;
}
a[last + 1] = data;
}
}
2、描述一个时间复杂度为o(nlgn)的算法找到在集合S中和为x的两个元素
基本思想:对集合s进行排序,时间复杂度为o(nlgn)的排序算法有快速排序,堆排序和归并排序。然后对已经排好序的序列进行一遍扫描找到两个元素。使得整个算法的时间复杂度为O(nlogn)。
实现算法(C#描述,VS205中调试通过,采用快速排序)
class ElementsInS
...{
static void Main(string[] args)
...{
Console.WriteLine("请输入数组S中的元素,以","分开");//输入数组S
string s =Console.ReadLine(); //生成数组S
string[] a = s.Split(',');
List<int> ls = new List<int>() ;
foreach(string t in a)
...{
int i;
if(int.TryParse(t,out i))
ls.Add(i);
}
Console.WriteLine("请输入数字S:");
int x =int.Parse(Console.ReadLine()); //输入和x
int[] aa = new int[ls.Count]; //从List copy数组s
ls.CopyTo(aa,0);
myQuickSort(aa, 0, ls.Count-1); //先对其进行快速排序时间复杂度为O(nlgn)
//以下循环一遍寻找两个元素
int f = 0;
int l = aa.Length-1;
while(f<l)
...{
if(aa[f]+aa[l] == x)
...{
Console.WriteLine("已经找到S的俩元素:" + aa[f].ToString() + "和" + aa[l].ToString());
break; //找到元素
}
else if(aa[f]+aa[l]>x) //两数和大数已知数时,移动尾游标
--l;
else //两数和小于已知数时, 移动头游标
++f;
}
if (f >= l)
...{
Console.WriteLine("数组s中没有和为" + x.ToString() + "的俩元素");
}
Console.ReadLine();
}
//以下为快速排序
private static void Swap(ref int i, ref int j)
//swap two integer
...{
int t;
t = i;
i = j;
j = t;
}
public static void Sort(int[] list, int low, int high)
...{
if (high <= low)
...{
//only one element in array list
//so it do not need sort
return;
}
else if (high == low + 1)
...{
//means two elements in array list
//so we just compare them
if (list[low] > list[high])
...{
//exchange them
Swap(ref list[low], ref list[high]);
return;
}
}
//more than 3 elements in the arrary list
//begin QuickSort
myQuickSort(list, low, high);
}
public static void myQuickSort(int[] list, int low, int high)
...{
if (low < high)
...{
int pivot = Partition(list, low, high);
myQuickSort(list, low, pivot - 1);
myQuickSort(list, pivot + 1, high);
}
}
private static int Partition(int[] list, int low, int high)
...{
//get the pivot of the arrary list
int pivot;
pivot = list[low];
while (low < high)
...{
while (low < high && list[high] >= pivot)
...{
high--;
}
if (low != high)
...{
Swap(ref list[low], ref list[high]);
low++;
}
while (low < high && list[low] <= pivot)
...{
low++;
}
if (low != high)
...{
Swap(ref list[low], ref list[high]);
high--;
}
}
return low;
}
}
相关文章推荐
- 判断序列中是否存在两个元素之和为x,时间复杂度O(nlgn),算法导论练习2.3,linux纯C实现
- 面试-链表逆置 作业手写一个单链表,并且实现单链表元素的逆置,(a0, a1,a2,a3,..an)-> (an,an-1,… a1, a0),算法的空间复杂度和时间复杂度经可能低
- 用线性时间复杂度实现找出数组中出现一次的元素
- 每天学习一算法系列(5)(已知两个数组,数组里的元素有正有负,但是都是按照从小到大已经排好序,要求用尽可能小的时间复杂度编写一算法求出两个数组的最大交集)
- 编写查找一个单链表特定元素的程序。分别使用递归和非递归方法实现,并比较它们的运行时间。
- 用线性时间复杂度实现找出数组中出现一次的元素
- 最小堆得实现;优先队列的堆实现;堆排序的时间复杂度nlgn;
- 每天学习一算法系列(5)(已知两个数组,数组里的元素有正有负,但是都是按照从小到大已经排好序,要求用尽可能小的时间复杂度编写一算法求出两个数组的最大交集)
- 斐波那契数列的递归与非递归算法实现及其时间复杂度
- 给定一个整数sum,从有N个无序元素的数组中寻找元素a、b、c、d,使得 a+b+c+d =sum,最快的平均时间复杂度是____。
- 用线性时间复杂度实现找出数组中出现一次的元素
- 描述一个运行时间为Θ(nlgn)的算法,给定n个整数的集合S和另一个整数x,该算法能确定S中是否存在两个其和刚好为x的元素
- 用线性时间复杂度实现找出数组中出现一次的元素
- 计数排序 求两个集合各自特有元素的并集 A-B并B-A 要求时间复杂度尽量的小
- 2.3-7 描述一个运行时间为Θ(nlgn)的算法,给定n个整数的集合S和另一个整数x,该算法能确定S中是否存在两个其和刚好为x的元素
- 寻找数列中多数元素(递归实现)
- 题目:请给出一个运行时间为Θ(nlgn)的算法,使之能在给定一个由n个整数构成的集合S和另一个整数x时,判断出S中是否存在有两个其和等于x的元素。
- 二分法实现插入排序,时间复杂度O(nlgn),算法导论练习2.3,linux纯C实现
- 题目1.请给出一个运行时间为O(nlgn)的算法,使之能在给定一个由n个整数构成的集合S和另一个证书x时,判断出S中是否存在有两个其和等于x的元素。
- 栈实现:入栈、出栈、取最小元素的时间复杂度都是O(1)。