您的位置:首页 > 其它

基本的查找你知道几个?

2013-07-07 01:22 225 查看

关于查找

查找又称检索,是从大量的数据中找出所需的数据,也可以简单地说是确定一个已给定的数据是否出现在某个数据表中。表通常是指文件,而文件是记录的集合,每个记录都是由若干个数据项组成的,其间一个或一组能唯一识别该记录的数据项称为该记录的关键字(keyword)。查找包括很多种:顺序查找、折半查找、分块查找以及哈希查找法。

顺序查找

核心思想:把序列中的元素进行遍历,找到符合条件的结果就结束

比较次数:最快1次,最慢n次

何时使用:

针对于无序序列,如果要实现查找序列中的所有满足条件的元素,那么比较次数一定是n次,因为找到其中一个,并不一定意味着找到所有的,因而要把所有的元素都遍历一遍才行。

如果是有序序列,要查找序列中所有满足条件的元素,比较次数要少一些,只需从开始满足的地方,到第一个不满足的地方就可以结束了,不必要等到序列末尾。

Search

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DataStructure
{
public interface IListDS<T>
{
int GetLength();             //求长度
void Clear();                //清空操作
bool IsEmpty();              //判断线性表是否为空
bool IsFull();               //判断数据表是否已满
void Append(T item);         //附加操作
void Insert(T item, int i);  //插入操作
T Delete(int i);             //删除操作
T GetElement(int i);         //取表元
int Locate(T value);         //按值查找
void Reserve();              //倒置
}

public class SeqList<T> : IListDS<T>
{
private int maxsize;        //顺序表的容量
private T[] data;           //数组,用于存储数据表中的数据元素
private int last;           //指示数据表中最后一个元素的位置

//索引器
public T this[int index]
{
get { return data[index]; }
set { data[index] = value; }
}

public T[] Data
{
get { return data; }
set { data = value; }
}

//属性 最后一个元素的位置
public int Last
{
get { return last; }
}

//属性 容量
public int Maxsize
{
get { return maxsize; }
set { maxsize = value; }
}

//构造函数
public SeqList(int size)
{
data = new T[size];
maxsize = size;
last = -1;
}

public int GetLength()
{
return last + 1;
}

public void Clear()
{
last = -1;
}

public bool IsEmpty()
{
if (last == -1)
return true;
else
return false;
}

public bool IsFull()
{
if (last == maxsize - 1)
return true;
else
return false;
}

public void Append(T item)
{
if (IsFull())
{
Console.WriteLine("List is full !");
return;
}
data[++last] = item;
}

public void Insert(T item, int i)
{
if (IsFull())
{
Console.WriteLine("List is Full !");
return;
}
if (i < 1 || i > last + 2)
{
Console.WriteLine("Postion is Error !");
return;
}
if (i == last + 2)
{
data[i - 1] = item;
}
else
{
for (int j = last; j >= i - 1; j--)
{
data[j + 1] = data[j];
}
data[i - 1] = item;
}
++last;
}

public T Delete(int i)
{
T tem = default(T);
if (IsEmpty())
{
Console.WriteLine("List is Empty !");
return tem;
}
if (i < 1 || i > last + 1)
{
Console.WriteLine("Postion is Error !");
return tem;
}
if (i == last + 1)
{
tem = data[last--];
return tem;
}
else
{
tem = data[i - 1];
for (int j = i; j <= last; j++)
{
data[j] = data[j + 1];
}
}
--last;
return tem;
}

public T GetElement(int i)
{
if (IsEmpty() || i < 1 || i > last + 1)
{
Console.WriteLine("List is Empty or Postion is Error !");
return default(T);
}
return data[i - 1];
}

public int Locate(T value)
{
if (IsEmpty())
{
Console.WriteLine("List is Empty !");
return -1;
}
int i = 0;
for (i = 0; i <= last; i++)
{
if (value.Equals(data[i]))
break;
}
if (i > last)
{
return -1;
}
return i;
}

public void Reserve()
{
T tem;
int len = GetLength();
for (int i = 0; i <= len / 2; i++)
{
tem = data[i];
data[i] = data[len - 1];
data[len - 1] = tem;
}
}

/// <summary>
/// 将两个升序整型顺序表合并成一个升序顺序表
/// 思路:依次扫描La Lb中的元素,比较La和Lb中当前元素,将较小的元素值赋值给Lc,如此直到一个被扫描完,然后把未完的那个剩余的元素付给Lc
/// </summary>
/// <param name="La"></param>
/// <param name="Lb"></param>
/// <returns></returns>
public SeqList<int> Merge(SeqList<int> La, SeqList<int> Lb)
{
SeqList<int> Lc = new SeqList<int>(La.Maxsize + Lb.Maxsize);
int i = 0;
int j = 0;

while ((i <= La.GetLength() - 1) && (j <= Lb.GetLength() - 1))
{
if (La[i] < Lb[j])
{
Lc.Append(La[i++]);
}
else
{
Lc.Append(Lb[j++]);
}
}
//如果La中还有元素
while (i <= La.GetLength() - 1)
{
Lc.Append(La[i++]);
}
//如果Lb中还有元素
while (i < Lb.GetLength() - 1)
{
Lc.Append(Lb[i++]);
}

return Lc;
}

/// <summary>
/// 已知顺序表La 构造顺序表Lb 使其包含La中所有不相同的数据元素
/// 思路: 先把La中的第一个元素付给Lb 然后从La的第二个元素开始 每一个元素与Lb的每一个元素比较 不同则附加到Lb末尾
/// </summary>
/// <param name="La"></param>
/// <returns></returns>
public SeqList<int> Purge(SeqList<int> La)
{
SeqList<int> Lb = new SeqList<int>(La.Maxsize);
Lb.Append(La[0]);
for (int i = 1; i <= La.GetLength() - 1; ++i)
{
int j = 0;
for (j = 0; j <= Lb.GetLength() - 1; ++j)
{
if (La[i].CompareTo(Lb[j]) == 0)
{
break;
}
}
//没有相同的元素,把La中的元素附加到Lb
if (j > Lb.GetLength() - 1)
{
Lb.Append(La[i]);
}
}
return Lb;
}

}

/// <summary>
/// 定义解决冲突的链表的结点类型
/// </summary>
public class chaintype
{
private int key;
private chaintype next;

public int Key
{
get { return key; }
set { key = value; }
}

public chaintype Next
{
get { return next; }
set { next = value; }
}
}

public class SearchArithMetic
{

/// <summary>
/// 插入排序
/// </summary>
/// <param name="R"></param>
public void InsertSort(SeqList<int> R)
{
for (int i = 1; i < R.Maxsize; i++)
{
if (R.Data[i] < R.Data[i - 1])
{
int temp = R.Data[i];
int j = 0;
for (j = i - 1; j >= 0 && temp < R.Data[j]; j--)
{
R.Data[j + 1] = R.Data[j];
}
R.Data[j + 1] = temp;
}
}
}

/// <summary>
/// 顺序查找算法
/// </summary>
/// <param name="R"></param>
/// <param name="Key"></param>
/// <returns></returns>
public int SeqSearch(SeqList<int> R, int Key)
{
int i;
R.Data[R.GetLength()] = Key;
for (i = 0; R.Data[i] != Key; i++) ;
if (i > R.Maxsize - 2)
return -2;
else
return i;
}

/// <summary>
/// 二分查找算法
/// </summary>
/// <param name="R"></param>
/// <param name="Key"></param>
/// <returns></returns>
public int BinSearch(SeqList<int> R, int Key)
{
int low = 0, high = R.GetLength() - 1, mid;  //设置当前查找区间的上下界的初值
while (low <= high)
{
mid = (low + high) / 2;
if (R.Data[mid] == Key) return mid;
if (R.Data[mid] > Key)
high = mid - 1;
else
low = mid + 1;
}
return -1;
}

/// <summary>
/// 除模取余法的哈希函数
/// </summary>
/// <param name="key"></param>
/// <param name="Mod"></param>
/// <returns></returns>
public int Hash(int key, int Mod)
{
return key % Mod;
}

/// <summary>
/// 在哈希表中插入记录,用链表法解决冲突
/// </summary>
/// <param name="a"></param>
/// <param name="key"></param>
/// <param name="Mod"></param>
/// <returns></returns>
public bool HashInsert(chaintype[] a, int key, int Mod)
{
int i;
i = Hash(key, Mod);
chaintype pre;
chaintype cur;
pre = a[i];
cur = a[i];

while (cur != null && cur.Key != key)
{
pre = cur;
cur = cur.Next;
}

/*未查找到时插入该记录在对应的链表尾*/
if (cur == null)
{
cur = new chaintype();
cur.Key = key;
cur.Next = null;
/*在该链插入第一个记录*/
if (a[i] == null)
a[i] = cur;
else
pre.Next = cur;
return true;
}
return false;
}

public chaintype HashSearch(chaintype[] a, int key, int Mod)
{
chaintype p;
int i = Hash(key, Mod);
p = a[i];
while (p != null && p.Key != key)
{ p = p.Next; }
if (p == null) return null;
else
return p;
}
}
class Search
{
/*
/// <summary>
/// 顺序查找
/// </summary>
/// <param name="R"></param>
/// <param name="Key"></param>
/// <returns></returns>
public static int SeqSearch(SeqList<int> R, int Key)
{
int i;
R.Data[R.GetLength()] = Key;
for (i = 0; R.Data[i] != Key; i++) ;
if (i > R.Maxsize - 2)
return -2;
else
return i;
}

/// <summary>
/// 二分查找
/// </summary>
/// <param name="R"></param>
/// <param name="Key"></param>
/// <returns></returns>
public static int BinSearch(SeqList<int> R, int Key)
{
int low = 0, high = R.GetLength() - 1, mid;  //设置当前查找区间的上下界的初值
while (low <= high)
{
mid = (low + high) / 2;
if (R.Data[mid] == Key) return mid;
if (R.Data[mid] > Key)
high = mid - 1;
else
low = mid + 1;
}
return -2;
}

static void Main()
{
SeqList<int> queue = new SeqList<int>(10);
queue.Append(10);
queue.Append(20);
queue.Append(30);
queue.Append(40);
queue.Append(50);
queue.Append(60);
queue.Append(70);
queue.Append(80);
queue.Append(90);

//int location = SeqSearch(queue, 90);
int location = BinSearch(queue, 90);
Console.WriteLine("您查找的数据为表中第{0}位!", location + 1);
Console.ReadKey();

}
*/

public static void Main()
{
SeqList<int> numList = null;

numList = new SeqList<int>(12);
chaintype[] a = new chaintype[13];

char selectFlag;
while (true)
{
Console.WriteLine("请输入操作选项:");
Console.WriteLine("1.创建顺序表");
Console.WriteLine("2.对顺序表执行顺序查找");
Console.WriteLine("3.对顺序表执行二分查找");
Console.WriteLine("4.创建哈希表");
Console.WriteLine("5.在哈希表中查找关键字");
Console.WriteLine("6.退出");
selectFlag = Convert.ToChar(Console.ReadLine());
SearchArithMetic searchA = new SearchArithMetic();
switch (selectFlag)
{
case '1':
{
numList.Insert(70, numList.GetLength() + 1);
numList.Insert(30, numList.GetLength() + 1);
numList.Insert(40, numList.GetLength() + 1);
numList.Insert(10, numList.GetLength() + 1);
numList.Insert(80, numList.GetLength() + 1);
numList.Insert(20, numList.GetLength() + 1);
numList.Insert(90, numList.GetLength() + 1);
numList.Insert(100, numList.GetLength() + 1);
numList.Insert(75, numList.GetLength() + 1);
numList.Insert(60, numList.GetLength() + 1);
numList.Insert(45, numList.GetLength() + 1);

Console.WriteLine("已插入顺序表的数字是:");
Console.WriteLine("70 30 40 10 80 20 90 100 75 60 45");
break;
}
case '2':
{
Console.WriteLine("请输入要查找的数字:");
long time1 = System.DateTime.Now.Ticks;
int num = Convert.ToInt32(Console.ReadLine());
int i = searchA.SeqSearch(numList, num);
if (i == -1)
Console.WriteLine("{0}在数字列表中不存在", num);
else
Console.WriteLine("{0}在数字列表中的序号为{1}", num, i);
long time2 = System.DateTime.Now.Ticks;
Console.WriteLine("顺序查找用时{0}", time2 - time1);
break;
}
case '3':
{
long time1 = System.DateTime.Now.Ticks;
new SearchArithMetic().InsertSort(numList);
long time2 = System.DateTime.Now.Ticks;
Console.WriteLine("请输入要查找的数字:");
int num = Convert.ToInt32(Console.ReadLine());
long time3 = System.DateTime.Now.Ticks;
int i = searchA.BinSearch(numList, num);
if (i == -1)
Console.WriteLine("{0}在数据列表中不存在", num);
else
Console.WriteLine("{0}在数字列表中的序号为{1}", num, i + 1);
long time4 = System.DateTime.Now.Ticks;
Console.WriteLine("排序用时{0}", time2 - time1);
Console.WriteLine("二分查找用时{0}", time4 - time3);
Console.WriteLine("查找总用时{0}", time4 - time1);
break;
}
case '4':
{
searchA.HashInsert(a, 70, 13);
searchA.HashInsert(a, 30, 13);
searchA.HashInsert(a, 40, 13);
searchA.HashInsert(a, 10, 13);
searchA.HashInsert(a, 80, 13);
searchA.HashInsert(a, 20, 13);
searchA.HashInsert(a, 90, 13);
searchA.HashInsert(a, 100, 13);
searchA.HashInsert(a, 75, 13);
searchA.HashInsert(a, 60, 13);
searchA.HashInsert(a, 45, 13);
break;
}
case '5':
{
Console.WriteLine("请输入要查找的数字:");
long time1 = System.DateTime.Now.Ticks;
int num = Convert.ToInt32(Console.ReadLine());
chaintype p = searchA.HashSearch(a, num, 13);
if(p==null)
Console.WriteLine("{0}在数据列表中不存在", num);
else
Console.WriteLine("您查找的关键字是:{0}",p.Key );
long time2 = System.DateTime.Now.Ticks;
Console.WriteLine("哈希表查找用时{0}", time2 - time1);
break;
}
case '6':
{
return;
}

}
Console.WriteLine("按任意键继续");
Console.ReadLine();
}
}

}
}


View Code

结语

适当的情景使用适当的算法,慢慢在实际中摸索,IT小菜鸟成长ing
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: