查找表 (search table) :由同一类型的数据元素 ( 或记录 ) 构成的集合。由于“集合”中的数据元素之间存在着松散的关系,因此查找表是一种应用灵便的数据结构,可以是线性表、树、图。关键字 (key) :数据元素 ( 或记录 ) 中某个数据项的值,用它可以标识 ( 识别 ) 一个数据元素( 或记录 ) 。如果一个关键字可以唯一地标识一个数据元素,则称其为主关键字;否则为次关键字。当数据元素仅有一个数据项,数据元素的值就是关键字。
#define MAXSIZE 20
typedef int KeyType;
typedef struct
{
KeyType r[MAXSIZE + 1];
int length;
}SqList;
void Init(SqList& L)
{
int i;
for (i = 0;i <= 20;i++)
L.r[i] = 0;
L.length = 0;
}
void Input(SqList& L)
{
int x;
while (cin >> x)
{
L.r[++L.length] = x;
if (cin.get() == '\n')
break;
}
}
算法思想:在表的一端设置一个称为“监视哨”的附加单元,存放要查找元素的关键字。从表的另端开始查找,如果未在“监视哨”找到要查找元素的关键字,返回失败信息,否则返回相应下标。
int SeqSearch(RecordList l,KeyType k)
//在顺序表|中顺序查找其关键字等于k的元素,若找到,则函数值为该元素在表中的位置,否则为 0
{
l.r[0].key=k; i=l.length;
while (l.r[i].key!=k)
i--;
return(i);
}
其中 1.r[0]为“监视哨”,可以起到防止越界的作用。
折半查找法又称为二分查找法,这种方法对待查找的列表有两个要求:
(1)必须采用顺序存储结构;
(2)必须按关键字大小有序排列。
算法思想:首先,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。
重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
int BinSrch (RecordList lKeyType k)
//在有序表|中折半查找其关键字等于k的元素,若找到,则函数值为该元素在表中的位置
{
low=1; high=l.length;//置区间初值
while (low<=high)
{
mid=(low+high)/2;
if(k==l.r[mid].key)
return(mid);//找到待査元素
else if(k
int main(void)
{
SqList L;
int key;
Init(L);
Input(L);
cin >> key;
Search(L, key);
return 0;
}
typedef struct node
{
KeyType key;
struct node *lchild, *rchild;
} BSTNode, *BSTree;
二叉排序树或者是一棵空树,或者是具有如下性质的二叉树:① 若它的左子树非空,则左子树上所有结点的值均小于根结点的值;② 若它的右子树非空,则右子树上所有结点的值均大于根结点的值;③ 它的左、右子树也分别是二叉排序树。
BSTree SearchBST(BSTree bt, KeyType key)
/*在根指针 bt 所指二叉排序树中,查找关键字等于 key 的元素,若查找成功,则返回指向该元
素的指针,否则返回空指针*/
{
if(!bt) return NULL;
else
if(bt->key==key) return bt; /*查找成功*/
else
if(keykey)
return SearchBST(bt->lchild, key); /*在左子树查找*/
else
return SearchBST(bt->rchild, key); /*在右子树查找*/
}
//构造哈希表
#include
#include
typedef struct Node {
int data;
struct Node* next;
} Node;
void initHashTable(Node** hashTable, int m) {
for (int i = 0; i < m; i++) {
hashTable[i] = NULL;
}
}
void insert(Node** head, int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
if (*head == NULL) {
*head = newNode;
} else {
Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
}
int hash(int key, int m) {
return key % m;
}
void printSynonyms(Node** hashTable, int n) {
Node* head = hashTable[n];
if (head == NULL) {
printf("-1");
} else {
Node* temp = head;
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
}
}
int main() {
int n;
int m;
int key;
int data;
Node* keywords = NULL;
while (scanf("%d", &key) != EOF) {
insert(&keywords, key);
if (getchar() == '\n') {
break;
}
}
// 输入哈希函数中的除数m
scanf("%d", &m);
// 输入散列地址n
scanf("%d", &n);
Node** hashTable = (Node**)malloc(m * sizeof(Node*));
initHashTable(hashTable, m);
Node* temp = keywords;
while (temp != NULL) {
int h = hash(temp->data, m);
insert(&hashTable[h], temp->data);
temp = temp->next;
}
// 输出散列地址n的同义词序列
printSynonyms(hashTable, n);
return 0;
}
根据在排序过程中涉及的存储器不同,可将排序方法分为两大类:内部排序、外部排序。内部排序:在排序进行的过程中不使用计算机外部存储器的排序过程。外部排序:在排序进行的过程中需要对外存进行访问的排序过程。
void SelectSort(SqList *L)
{ /*对顺序表 L 作简单选择排序*/
RecordType temp;
for(i=1; ilength; ++i)
{ /*选择第 i 个小的记录,并交换到位*/
j=i; /* j 用于记录最小元素的位置*/
for(k=i+1; k<=L->length; k++) /*在 L.r[i..L.length]中选择 key 最小的记录*/
if(L->r[k].keyr[j].key)
j=k;
if(i!=j) /*第 i 个小的记录 L->r[j]与第 i 个记录交换*/
{
temp=L->r[j];
L->r[j]=L->r[i];
L->r[i]=temp;
}
}
}/*SelectSort
void InsertSort(SqList *L)
{ /*对顺序表 L 作插入排序*/
for(i=2; i<=L->length; ++i)
if(L->r[i].keyr[i-1].key)
{ /*当“<”时,才需将 L->r[i]插入有序表*/
L->r[0]=L->r[i]; /*将待插入记录复制为哨兵*/
j=i-1;
while(L->r[0].keyr[j].key)
{
L->r[j+1]=L->r[j]; /*记录后移*/
j--;
}
L->r[j+1]=L->r[0]; /*插入到正确位置*/
}
}