1.二分查找和顺序查找
二分查找:
class TestSearch
{
public static int BinarySearch(int[] arr, int target)
{
int l = 0;
int r = arr.Length - 1;
while (l <= r)
{
//int mid = (l + r) / 2; //l和r都是大整型时,可能会溢出
int mid = l + (r - l) / 2;
if (target < arr[mid])
{
r = mid - 1;
}
else if (target > arr[mid])
{
l = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
}
2.查找算法性能比较
class Program
{
static void Main(string[] args)
{
string filename3 = "测试文件2/游戏会员表.txt";
string filename4 = "测试文件2/游戏用户表.txt";
int[] arr3 = TestSearch.ReadFile(filename3);
int[] arr4 = TestSearch.ReadFile(filename4);
Console.WriteLine("游戏会员数量:" + arr3.Length);
Console.WriteLine("调查用户数量:" + arr4.Length);
Console.WriteLine();
Stopwatch t3 = new Stopwatch();
Stopwatch t4 = new Stopwatch();
Console.WriteLine("顺序查找法");
t3.Start();
int sum3 = 0;
for (int i = 0; i < arr4.Length; i++)
{
int target = arr4[i];
if (TestSearch.OrderSearch(arr3, target) == -1)
sum3++;
}
t3.Stop();
Console.WriteLine("查找到:" + sum3 + "个普通玩家");
Console.WriteLine("运行时间:" + t3.ElapsedMilliseconds + "ms");
Console.WriteLine();
Console.WriteLine("二分查找法");
t4.Start();
Array.Sort(arr3);
int sum4 = 0;
for (int i = 0; i < arr4.Length; i++)
{
int target = arr4[i];
if (TestSearch.BinarySearch(arr3, target) == -1)
{
sum4++;
}
}
t4.Stop();
Console.WriteLine("查找到:" + sum4 + "个普通玩家");
Console.WriteLine("运行时间:" + t4.ElapsedMilliseconds + "ms");
Console.Read();
}
}
3.什么是有序数组
有序数组(Rank方法):
class SortedArray1<Key> where Key : IComparable<Key>
{
private Key[] keys;
private int N;
public SortedArray1(int capacity)
{
keys = new Key[capacity];
}
public SortedArray1() : this(10) { }
public int Count { get { return N; } }
public bool ISEmpty { get { return N == 0; } }
public int Rank(Key key)
{
int l = 0;
int r = N - 1;
while (l <= r)
{
//int mid = (l + r) / 2; //l和r都是大整型时,可能会溢出
int mid = l + (r - l) / 2;
if (key.CompareTo(keys[mid]) < 0)
r = mid - 1; //在keys[l...mid-1]查找key
else if (key.CompareTo(keys[mid]) > 0)
l = mid + 1; //在keys[mid+1...r]查找key
else
return mid; //找到key,并返回索引
}
return l;
}
}
4.添加、删除元素
添加:
public void Add(Key key)
{
int i = Rank(key);
if (i < N && keys[i].CompareTo(key) == 0)
return;
for (int j = N-1; j >= i; j--)
keys[j + 1] = keys[j];
keys[i] = key;
N++;
}
删除:
public void Remove(Key key)
{
if (IsEmpty)
return;
int i = Rank(key);
if (i == N || keys[i].CompareTo(key) != 0)
return;
for (int j = i+1; j <= N-1; j++)
keys[j - 1] = keys[j];
N--;
keys[N] = default(Key);
}
5.其他有序性相关方法
有序数组完整代码:
class SortedArray1<Key> where Key : IComparable<Key>
{
private Key[] keys;
private int N;
public SortedArray1(int capacity)
{
keys = new Key[capacity];
}
public SortedArray1() : this(10) { }
public int Count { get { return N; } }
public bool IsEmpty { get { return N == 0; } }
public int Rank(Key key)
{
int l = 0;
int r = N - 1;
while (l <= r)
{
//int mid = (l + r) / 2; //l和r都是大整型时,可能会溢出
int mid = l + (r - l) / 2;
if (key.CompareTo(keys[mid]) < 0)
r = mid - 1; //在keys[l...mid-1]查找key
else if (key.CompareTo(keys[mid]) > 0)
l = mid + 1; //在keys[mid+1...r]查找key
else
return mid; //找到key,并返回索引
}
return l;
}
public void Add(Key key)
{
int i = Rank(key);
if (N == keys.Length) //扩容
ResetCapacity(2 * keys.Length);
if (i < N && keys[i].CompareTo(key) == 0)
return;
for (int j = N - 1; j >= i; j--)
keys[j + 1] = keys[j];
keys[i] = key;
N++;
}
public void Remove(Key key)
{
if (IsEmpty)
return;
int i = Rank(key);
if (i == N || keys[i].CompareTo(key) != 0)
return;
for (int j = i + 1; j <= N - 1; j++)
keys[j - 1] = keys[j];
N--;
keys[N] = default(Key);
if (N == keys.Length / 4) //缩容
ResetCapacity(keys.Length / 2);
}
public Key Min()
{
if (IsEmpty)
throw new ArgumentException("数组为空!");
return keys[0];
}
public Key Max()
{
if (IsEmpty)
throw new ArgumentException("数组为空!");
return keys[N - 1];
}
public Key Select(int k)
{
if (k < 0 || k >= N)
throw new ArgumentException("索引越界!");
return keys[k];
}
public bool Contains(Key key)
{
int i = Rank(key);
if (i < N && keys[i].CompareTo(key) == 0)
return true;
return false;
}
//找出小于或等于key的最大键
public Key Floor(Key key)
{
int i = Rank(key);
if (i < N && keys[i].CompareTo(key) == 0)
return keys[i];
if (i == 0)
throw new ArgumentException("没有找到小于或等于" + key + "的最大键");
else
return keys[i - 1];
}
//找出大于或等于key的最小键
public Key Ceiling(Key key)
{
int i = Rank(key);
if (i == N)
throw new ArgumentException("没有找到大于或等于" + key + "的最小键");
else
return keys[i];
}
//调整数组容量大小
private void ResetCapacity(int newCapacity)
{
Key[] newKeys = new Key[newCapacity];
for (int i = 0; i < N; i++)
{
newKeys[i] = keys[i];
}
keys = newKeys;
}
//输出链表类信息
public override string ToString()
{
StringBuilder res = new StringBuilder();
res.Append("[");
for (int i = 0; i < N; i++)
{
res.Append(keys[i]);
if (i != N - 1)
res.Append(", ");
}
res.Append("]");
return res.ToString();
}
}
测试整型:
class Program
{
static void Main(string[] args)
{
int[] arr = { 84, 48, 68, 10, 18, 98, 12, 23, 54, 57, 33, 16, 77, 11, 29 };
SortedArray1<int> sortedArray1 = new SortedArray1<int>();
for (int i = 0; i < arr.Length; i++)
sortedArray1.Add(arr[i]);
Console.WriteLine(sortedArray1);
Console.WriteLine(sortedArray1.Min());
Console.WriteLine(sortedArray1.Max());
Console.WriteLine(sortedArray1.Select(5));
Console.WriteLine(sortedArray1.Floor(15));
Console.WriteLine(sortedArray1.Ceiling(15));
sortedArray1.Remove(23);
Console.WriteLine(sortedArray1);
Console.Read();
}
}
创建学生类:
class Student:IComparable<Student>
{
//Student是一个可比较的类型
//实现了IComparable<Student>接口中的比较方法CompareTo()
private string name;
private int tall;
public Student(string name,int tall)
{
this.name = name;
this.tall = tall;
}
//自定义比较大小的方法
//通过身高进行比较
public int CompareTo(Student other)
{
if (this.tall > other.tall) return 1;
if (this.tall < other.tall) return -1;
return 0;
}
public override string ToString()
{
return "{" + name + ":" + tall + "}";
}
}
测试学生类排序:
class Program
{
static void Main(string[] args)
{
Student[] students =
{
new Student("小明",180),
new Student("小红",150),
new Student("小芳",175),
new Student("小华",160),
new Student("小李",190),
};
SortedArray1<Student> s = new SortedArray1<Student>();
for (int i = 0; i < students.Length; i++)
s.Add(students[i]);
Console.WriteLine(s);
Console.Read();
}
}