}
/**********
【题目】试写一算法,实现链栈的取栈顶元素操作。
链栈的类型定义为:
typedef struct LSNode {
ElemType data; // 数据域
struct LSNode *next; // 指针域
} LSNode, *LStack; // 结点和链栈类型
***********/
Status GetTop_L(LStack S, ElemType &e)
/* 取链栈S的栈顶元素到e,并返回OK; */
/* 若S是空栈,则失败,返回ERROR。 */
{
if(NULL==S)return ERROR;
e=S->data;
S=S->next;
return OK;
}
/**********
【题目】试写一算法,实现链队列的判空操作。
链队列的类型定义为:
typedef struct LQNode {
ElemType data;
struct LQNode *next;
} LQNode, *QueuePtr; // 结点和结点指针类型
typedef struct {
QueuePtr front; // 队头指针
QueuePtr rear; // 队尾指针
} LQueue; // 链队列类型
***********/
Status QueueEmpty_LQ(LQueue Q)
/* 判定链队列Q是否为空队列。 */
/* 若Q是空队列,则返回TRUE,否则FALSE。*/
{
if(Q.front==Q.rear&&Q.front==NULL) return TRUE;
return FALSE;
}
/**********
【题目】试写一算法,实现链队列的求队列长度操作。
链队列的类型定义为:
typedef struct LQNode {
ElemType data;
struct LQNode *next;
} LQNode, *QueuePtr; // 结点和结点指针类型
typedef struct {
QueuePtr front; // 队头指针
QueuePtr rear; // 队尾指针
} LQueue; // 链队列类型
***********/
int QueueLength_LQ(LQueue Q)
/* 求链队列Q的长度并返回其值 */
{
int length=1;
LQNode *p;
if(Q.front==Q.rear&&Q.rear==NULL)return 0;
if(Q.front==Q.rear&&Q.rear!=NULL)return 1;
while(Q.rear!=Q.front){
p=Q.front;
Q.front=p->next;
length++;
}
return length;
}
/**********
【题目】假设以带头结点的循环链表表示队列,并且
只设一个指针指向队尾元素结点(注意不设头指针),
试编写相应的队列初始化、入队列和出队列的算法。
带头结点循环链队列CLQueue的类型定义为:
typedef struct LQNode {
ElemType data;
struct LQNode *next;
} LQNode, *CLQueue;
**********/
Status InitCLQueue(CLQueue &rear) // 初始化空队列
{
rear = (LQNode*)malloc(sizeof(LQNode));
rear->next = rear;
return OK;
}
Status EnCLQueue(CLQueue &rear, ElemType x) // 入队
{
LQNode *p;
p = (LQNode*)malloc(sizeof(LQNode));
p->data = x;
p->next = rear->next;
rear->next = p;
rear = p;
return OK;
}
Status DeCLQueue(CLQueue &rear, ElemType &x) // 出队
{
LQNode *p;
if(rear==rear->next)
return ERROR;
p = rear->next->next;
x = p->data;
rear->next->next = p->next;
free(p);
return OK;
}
/**********
【题目】试写一算法,实现带头结点单链表的判空操作。
单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList; // 结点和结点指针类型
***********/
Status ListEmpty_L(LinkList L)
/* 判定带头结点单链表L是否为空链表。 */
/* 若L是空链表,则返回TRUE,否则FALSE。*/
{
if(L->next!=NULL)return FALSE;
return TRUE;
}
/**********
【题目】试写一算法,实现带头结点单链表的销毁操作。
单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList; // 结点和结点指针类型
***********/
Status DestroyList_L(LinkList &L)
/* 销毁带头结点单链表L,并返回OK。*/
{
L=NULL;
return OK;
}
/**********
【题目】试写一算法,实现带头结点单链表的清空操作。
单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList; // 结点和结点指针类型
***********/
Status ClearList_L(LinkList &L)
/* 将带头结点单链表L置为空表,并返回OK。*/
/* 若L不是带头结点单链表,则返回ERROR。 */
{
if(L==NULL)return ERROR;
L->next=NULL;
return OK;
}
/**********
【题目】试写一算法,实现带头结点单链表的求表长度操作。
单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList; // 结点和结点指针类型
***********/
int ListLength_L(LinkList L)
/* 求带头结点单链表L的长度,并返回长度值。*/
/* 若L不是带头结点单链表,则返回-1。 */
{
int length=0;
if(L==NULL)return -1;
while(L->next){
L=L->next;
length++;
}
return length;
}
/**********
【题目】试写一算法,在带头结点单链表L插入第i元素e。
带头结点单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
**********/
Status Insert_L(LinkList L, int i, ElemType e)
/* 在带头结点单链表L插入第i元素e,并返回OK。*/
/* 若参数不合理,则返回ERROR。 */
{
int k=0;
LNode *p=L,*q;
while(p&&k<i-1)
{
p=p->next;
k++;
}
if(!p||k>i-1)return ERROR;
q = (LinkList)malloc(sizeof(struct LNode));
q->data=e;
q->next=p->next;
p->next=q;
return OK;
}
/**********
【题目】试写一算法,在带头结点单链表删除第i元素到e。
带头结点单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
**********/
Status Delete_L(LinkList L, int i, ElemType &e)
/* 在带头结点单链表L删除第i元素到e,并返回OK。*/
/* 若参数不合理,则返回ERROR。 */
{
int j=0;
LinkList p=L,q;
while(p->next && j < i-1) /* 寻找第i个结点,并令p指向其前岖 */
{
p = p->next;
j++;
}
if( !p->next || j > i-1) /* 删除位置不合理 */
return ERROR;
q = p->next; /* 删除并释放结点 */
p->next = q->next;
e = q->data;
free(q);
return OK;
}
/**********
【题目】试写一算法,在带头结点单链表的第i元素起的
所有元素从链表移除,并构成一个带头结点的新链表。
带头结点单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
**********/
Status Split_L(LinkList L, LinkList &Li, int i)
/* 在带头结点单链表L的第i元素起的所有元素 */
/* 移除,并构成带头结点链表Li,返回OK。 */
/* 若参数不合理,则Li为NULL,返回ERROR。 */
{
int j=0;
LinkList p=L;
while(p->next && j < i-1) /* 寻找第i个结点,并令p指向其前 */
{
p = p->next;
j++;
}
if( !p->next || j > i-1) /* 位置不合理 */
{
Li=NULL;
return ERROR;
}
Li = (LNode*)malloc(sizeof(LNode));
Li->next=p->next;
p->next=NULL;
return OK;
}
/**********
【题目】试写一算法,在带头结点单链表删除第i元素
起的所有元素。
带头结点单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
**********/
Status Cut_L(LinkList L, int i)
/* 在带头结点单链表L删除第i元素起的所有元素,并返回OK。*/
/* 若参数不合理,则返回ERROR。 */
{
int j=0;
LinkList p=L;
while(p->next && j < i-1) /* 寻找第i个结点,并令p指向其前 */
{
p = p->next;
j++;
}
if( !p->next || j > i-1) /* 位置不合理 */
return ERROR;
p->next=NULL;
return OK;
}
/**********
【题目】试写一算法,在带头结点单链表删除第i元素
起的所有元素。
带头结点单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
**********/
Status Cut_L(LinkList L, int i)
/* 在带头结点单链表L删除第i元素起的所有元素,并返回OK。*/
/* 若参数不合理,则返回ERROR。 */
{
int j=0;
LinkList p=L;
while(p->next && j < i-1) /* 寻找第i个结点,并令p指向其前 */
{
p = p->next;
j++;
}
if( !p->next || j > i-1) /* 位置不合理 */
return ERROR;
p->next=NULL;
return OK;
}
/**********
【题目】试以顺序表L的L.rcd[L.length+1]作为监视哨,
改写教材5.2节中给出的升序直接插入排序算法。
顺序表的类型RcdSqList定义如下:
typedef struct {
KeyType key;
...
} RcdType;
typedef struct {
RcdType rcd[MAXSIZE+1]; // r[0]闲置
int length;
} RcdSqList;
**********/
void InsertSort(RcdSqList &L)
{
int i,j;
for(i=1;i<L.length;++i)
if(L.rcd[i+1].key<L.rcd[i].key) {
L.rcd[L.length+1]=L.rcd[i+1];
j=i+1;
do{j--;L.rcd[j+1]=L.rcd[j];
}while(L.rcd[L.length+1].key<L.rcd[j-1].key);
L.rcd[j]=L.rcd[L.length+1];
}
}
/**********
【题目】如下所述,改写教材1.5节的冒泡排序算法:
将算法中用以起控制作用的布尔变量change改为一个整型
变量,指示每一趟排序中进行交换的最后一个记录的位置,
并以它作为下一趟起泡排序循环终止的控制值。
顺序表的类型RcdSqList定义如下:
typedef struct {
KeyType key;
...
} RcdType;
typedef struct {
RcdType rcd[MAXSIZE+1]; // r[0]闲置
int length;
} RcdSqList;
**********/
void BubbleSort(RcdSqList &L)
/* 元素比较和交换必须调用如下定义的比较函数和交换函数:*/
/* Status LT(RedType a, RedType b); 比较:"<" */
/* Status GT(RedType a, RedType b); 比较:">" */
/* void Swap(RedType &a, RedType &b); 交换 */
{
int i,j=0,change=1;
for(i=L.length;i>1;i=change)
{
change=1;
for(j=1;j<i;j++)
{
if(GT(L.rcd[j],L.rcd[j+1]))
{
Swap(L.rcd[j],L.rcd[j+1]);
change=j;
}
}
}
}
/**********
【题目】已知记录序列L.rcd[1..L.length]中的关键
字各不相同,可按如下所述实现计数排序:另设数组
c[1..n],对每个记录a[i], 统计序列中关键字比它
小的记录个数存于c[i],则c[i]=0的记录必为关键字
最小的记录,然后依c[i]值的大小对序列中记录进行
重新排列。试编写算法实现上述排序方法。
顺序表的类型RcdSqList定义如下:
typedef struct {
KeyType key;
...
} RcdType;
typedef struct {
RcdType rcd[MAXSIZE+1]; // r[0]闲置
int length;
} RcdSqList;
**********/
void CountSort(RcdSqList &L)
/* 采用顺序表存储结构,在函数内自行定义计数数组c */
{
int i,j,count;
int c[100];
RcdSqList s;
for(i=1;i<=L.length;i++)
{ count=0;
for(j=1;j<=L.length;j++)
if(L.rcd[i].key>L.rcd[j].key)count++;
c[i-1]=count;}
for(i=1;i<=L.length;i++)
s.rcd[i]=L.rcd[i];
s.length=L.length;
for(i=0;i<L.length;i++)
L.rcd[c[i]+1]=s.rcd[i+1];
}
/**********
【题目】已知某哈希表的装载因子小于1,哈希函数H(key)
为关键字(标识符)的第一个字母在字母表中的序号,处理
冲突的方法为线性探测开放定址法。试编写一个按第一个
字母的顺序输出哈希表中所有关键字的算法。
哈希表的类型HashTable定义如下:
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1
typedef char StrKeyType[4];
typedef struct {
StrKeyType key; // 关键字项
int tag; // 标记 0:空;1:有效; -1:已删除
void *any; // 其他信息
} RcdType;
typedef struct {
RcdType *rcd; // 存储空间基址
int size; // 哈希表容量
int count; // 表中当前记录个数
} HashTable;
**********/
void PrintKeys(HashTable ht, void(*print)(StrKeyType))
/* 依题意用print输出关键字 */
{
int n,i,size;
char c;
size=11;
for(c='A';c<='Z';c++) {
n=(c-'A')%size;
i=n;
while((n+1)%size!=i) {
if(ht.rcd[n].key[0]==c&&ht.rcd[n].tag==1)
print(ht.rcd[n].key);
n=(n+1)%size;
}
}
}
/**********
【题目】假设哈希表长为m,哈希函数为H(x),用链地址法
处理冲突。试编写输入一组关键字并建造哈希表的算法。
哈希表的类型ChainHashTab定义如下:
#define NUM 7
#define NULLKEY -1
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1
typedef char HKeyType;
typedef struct HNode {
HKeyType data;
struct HNode* next;
}*HLink;
typedef struct {
HLink *rcd; // 指针存储基址,动态分配数组
int count; // 当前表中含有的记录个数
int size; // 哈希表的当前容量
}ChainHashTab; // 链地址哈希表
int Hash(ChainHashTab H, HKeyType k) { // 哈希函数
return k % H.size;
}
Status Collision(ChainHashTab H, HLink &p) {
// 求得下一个探查地址p
if (p && p->next) {
p = p->next;
return SUCCESS;
} else return UNSUCCESS;
}
**********/
int BuildHashTab(ChainHashTab &H, int n, HKeyType es[])
/* 直接调用下列函数 */
/* 哈希函数: */
/* int Hash(ChainHashTab H, HKeyType k); */
/* 冲突处理函数: */
/* int Collision(ChainHashTab H, HLink &p); */
{
HLink p,q;
int i,pos;
for(i=0;i<n;i++) H.rcd[i]->next=NULL;
for(i=0;i<n;i++)
{
q=(HNode*)malloc(sizeof(HNode));
q->data=es[i];q->next=NULL; //建立新结点
pos=Hash(H,es[i]); //查找位置
p=H.rcd[pos];
while(p->data!=q->data&&p->next) Collision(H,p); //确定是否出现过
if(p->data!=q->data) //新元素,插在前面
{q->next=H.rcd[pos];
H.rcd[pos]=q;}//if
}//for
return OK ;
}