文章目录
- 一、线性表
- 1、已知p指向双向循环链表中的一个结点,交换p所指向的结点及其前驱结点的顺序。
- 2、HL是单链表的头指针,试写出删除头结点的算法。
- 3、统计出单链表HL中结点的值等于给定值X的结点数。
- 4、将一个结点类型为Lnode的单链表按逆序链接。
- 5、判断单链表中结点是否关于中心对称。
- 6、设计在单链表中删除值相同的多余结点的算法。
- 7、设单链表中有仅三类字符的数据元素(大写字母、数字和其它字符),要求利用原单链表中结点空间设计出三个单链表的算法,使每个单链表只包含同类字符。
- 8、设计两个有序单链表的合并排序算法。
- 9、设有两个集合A和集合B,要求设计生成集合C=A∩B的算法,其中集合A、B和C用链式存储结构表示。
- 10、设计在顺序存储结构上实现求子串算法。
- 11、判断单链表中元素是否是递增。
- 二、栈和队列
- 三、数组和广义表
- 四、树和二叉树
- 五、图
- 六、查找
- 七、排序
- 1、对一整型数组b[n]中的元素进行重新排列,将所有负数均调整到数组的低下标端,将所有正数均调整到数组的高下标端,若有零值,则置于两者之间,并返回数组中零元素的个数。
- 2、设有一组初始记录关键字序列(K1,K2,…,Kn),要求设计一个算法能够在O(n)的时间复杂度内将线性表划分成两部分,其中左半部分的每个关键字均小于Ki,右半部分的每个关键字均大于等于Ki。
- 3、 在链式存储结构上设计直接插入排序算法。
- 4、设计在链式结构上实现简单选择排序算法。
- 5、设计将所有奇数移到所有偶数之前的算法。
- 6、设计在链式存储结构上合并排序的算法。
- 7、设关键字序列(k1,k2,…,kn-1)是堆,设计算法将关键字序列(k1,k2,…,kn-1,x)调整为堆。
一、线性表
1、已知p指向双向循环链表中的一个结点,交换p所指向的结点及其前驱结点的顺序。
typedef struct DNode{
int data;
struct DNode* prior; //前驱
struct DNode* next; //后继
}DNode, *LinkList;
void swap(DNode *p) //交换p结点与其前驱结点的位置
{
DNode *q=p->prior; //q是p的前驱结点
q->prior->next=p;
p->prior=q->prior;
p->next->prior=q;
q->next=p->next;
q->prior=p;
p->next=q;
}
分三个阶段:
1、p与新前驱建立联系:
q->prior->next=p;
p->prior=q->prior;
.
2、q与新后继建立联系:
p->next->prior=q;
q->next=p->next;
.
3、p与q互连:
p->next=q;
q->prior=p;
注意:在交换过程中不能丢掉前后两端结点的地址,也就是在任何时候都应该可以得到两端的结点。
2、HL是单链表的头指针,试写出删除头结点的算法。
ElemType DeleFront(LNode * & HL)
{
if (HL==NULL){
cerr<<"空表"<<endl;
exit(1);
}
LNode* p=HL;
HL=HL->next;
ElemType temp=p->data;
delete p;
return temp;
}
3、统计出单链表HL中结点的值等于给定值X的结点数。
int CountX(LNode* HL,ElemType x)
{
int i=0; //i为计数器
LNode *p=HL;
while(p){
if(x==p->data) i++;
p=p-next;
} //出循环时i中的值即为x结点个数
return i;
}
4、将一个结点类型为Lnode的单链表按逆序链接。
void contrary(Lnode *& HL)
{
Lnode *p=HL;
HL=NULL;
while(p){
Lnode *q=p;
p=p->next;
q->next=HL;
HL=q;
}
}
5、判断单链表中结点是否关于中心对称。
typedef struct{int s[100]; int top;}sqstack;
int lklistSymmetry(lklist *head)
{
sqstack stack;
stack.top=-1;
lklist *p;
for(p=head; p!=0; p->next){
stack.top++;
stack.s[stack.top]=p->data;
}
for(p=head; p!0; p=p->next){
if(p->data == stack.s[stack.top])
stack.top--;
else return 0;
}
return 1;
}
6、设计在单链表中删除值相同的多余结点的算法。
typedef int datatype;
typedef struct node{datetype data; struct node *next;}lklist;
void deleteRedundant(lklist *&head)
{
lklist *p,*q,*s;
for(p=head; p!=0; p=p->next){
for(q=p->next,s=q;q!=0; ){
if(q->data==p->data){
s->next=q->next;
free(q);
q=s->next;
}
else{
s=q;
q=q->next;
}
}
}
}
7、设单链表中有仅三类字符的数据元素(大写字母、数字和其它字符),要求利用原单链表中结点空间设计出三个单链表的算法,使每个单链表只包含同类字符。
typedef struct node{char data; struct node *next;}lklist;
void split(lklist *head, lklist *&ha, lklist *&hb, lklist *&hc)
{
lklist *p;
ha=0,hb=0,hc=0;
for(p=head; p!=0; p=head){
head=p->next;
p->next=0;
if('A'<=p->data && p->data<='Z'){p->next=ha; ha=p;}
else if('0'<=p->data && p->data<='9') {p->next=hb;hb=p;}
else {p->next=hc; hc=p;}
}
}
8、设计两个有序单链表的合并排序算法。
typedef struct node{int data; struct node *next;} lklist;
void merge(lklist *ha, lklist *hb, lklist *&hc)
{
lklist *s=hc=0;
while(ha!=0 && hb!=0){
if(ha->data < hb->data){
if(s==0) hc=s=ha;
else {s->next=ha; s=ha;}
ha=ha->next;
}
else {
if(s==0) hc=s=hb;
else {s->next=hb; s=hb;}
hb=hb->next;
}
}
if(ha==0) s->next=hb;
else s->next=ha;
}
9、设有两个集合A和集合B,要求设计生成集合C=A∩B的算法,其中集合A、B和C用链式存储结构表示。
typedef struct node{
int data;
struct node *next;
}lklist;
void intersection(lklist *ha, lklist *hb, lklist *&hc)
{
lklist *p,*q,*t;
for(p=ha,hc=0; p!=0; p=p->next){
for(q=hb; q!=0; q=q->next)
if(p->data == q->data) break;
if(q!=0){
t=(lklist*)malloc(sizeof(lklist));
t->data=p->data;
t->next=hc;
hc=t;
}
}
}
10、设计在顺序存储结构上实现求子串算法。
void SubString(char s[],int start,int n,char t[])
{
int i,j,length=strlen(s);
if(start<1 || start>length) printf("The position is wrong.");
if(start+n-1>length) printf("Too many characters to be copied.");
else{
for(i=start-1,j=0; i<start+n-1; i++,j++) t[j]=s[i];
t[j]='\0';
}
}
11、判断单链表中元素是否是递增。
int isincrease (lklist *head)
{
lklist *p,*q;
if(head==0 || head->next==0) return 1;
for(q=head,p=head->next; p!=0; q=p,p=p->next){ //q在p前一个
if(q->data > p->data) //如果存在递减对
return 0;
}
return 1;
}
二、栈和队列
三、数组和广义表
四、树和二叉树
1、在链式存储结构上建立一棵二叉树。
typedef char datatype;
typedef struct node{datatype data;struct node *lchild,*rchild;} bitree;
void createbitree(bitree *&bt)
{
char ch;
scanf("%c",&ch);
if(ch=='#'){
bt=0;
return;
}
bt=(bitree*)malloc(sizeof(bitree));
bt->data=ch;
createbitree(bt->lchild);
createbitree(bt->rchild);
}
2、判断一棵二叉树是否是二叉排序树。
int minnum=-32768,flag=1;
typedef struct node{int key; struct node *lchild,*rchild;} bitree;
void inorder(bitree *bt) //中序遍历二叉排序树,结点值应该是递增的
{
if(bt){
inorder(bt->lchild);
if(minnum > bt->key) flag=0;
minnum = bt->key;
inorder(bt->rchild);
}
}
3、在链式存储结构上建立一棵二叉排序树。
#definde N 10
typedef struct node{int key; struct node *lchild,*rchild;}bitree;
void BSTinsert(bitree *&bt, int key)
{
if(bt==0){
bt=(bitree*)malloc(sizeof(bitree));
bt->key=key;
bt->lchild=bt->rchild=0;
}
else if(key < bt->key) BSTinsert(bt->lchild,key);
else BSTinsert(bt->rchild,key);
}
void CreateBST(bitree *&bt)
{
for(int i=0;i<N;i++)
BSTinsert(bt,random(100));
}
4、设计一个求结点x在二叉树中的双亲结点算法。
#define N 20
typedef struct node{
int data;
struct node *lchild, *rchild;
}bitree;
bitree *q[N];
int r=0,f=0,flag=0;
void preorder(bitree *bt, int x)
{
if(bt!=0 && flag==0){
if(bt->data==x){
falg=1;
return;
}
else{
r=(r+1)%N;
q[r]=bt;
preorder(bt->lchild,x);
preorder(bt->rchild,x);
}
}
}
void parent(bitree *bt,int x)
{
int i;
preorder(bt,x);
for(i=f+1; i<=r; i++){
if(q[i]->lchild->data==x || q[i]->rchild->data==x) break;
}
if(flag==0) printf("not found x.\n");
else if(i<=r && flag==1) printf("parent: %d\n",q[i]->data);
else printf("not parent.\n");
}
5、设计在链式存储结构上交换二叉树中所有结点左右子树的算法。
typedef struct node{int data; struct node *lchild,*rchild;} bitree;
void swap(bitree *bt)
{
bitree *p;
if(bt==0) return;
swap(bt->lchild);
swap(bt->rchild);
p=bt->lchild; bt->lchild=bt->rchild; bt->rchild=p;
}
6、设计判断两个二叉树是否相同的算法。
typedef struct node{int data; struct node *lchild,*rchild;} bitree;
int judge(bitree *bt1, bitree *bt2)
{
if(bt1==0 && bt2==0) return 1;
if(bt1==0 || bt2==0 || bt1->data!=bt2->data) return 0;
return judge(bt1->lchild,bt2->lchild)*judge(bt1->rchild,bt2->rchild);
}
7、设计求结点在二叉排序树中层次的算法。
int lev=0;
typedef struct node{int key; struct node *lchild,*rchild;}bitree;
void level(bitree *bt,int x)
{
if(bt){
lev++;
if(x == bt->key) return;
else if(x < bt->key) level(bt->lchild,x);
else level(bt->rchild,x);
}
}
8、设计在链式存储结构上统计二叉树中结点个数的算法。
void count(bitree *bt,&num)
{
if(bt){
num++;
count(bt->lchild,num);
count(bt->rchild,num);
}
}
9、计算二叉树中所有结点值之和。
void sum(bitree *bt,long &sum)
{
if(bt){
sum+=bt->data;
sum(bt->lchild,sum);
sum(bt->rchild,sum);
}
}
五、图
1、设计算法将无向图的邻接矩阵转为对应邻接表的算法。
typedef struct{int vertex[m]; int edge[m][m];int vexn,arcn;}adjmatrix;
typedef struct node1{int adjvex;int adjvertex;struct node1 *nextarc;}edgeode;
typedef struct node2{int data;edgenode *firstarc;}adjlist;
void adjmatrixtoadjlist(adjmatrix g1, adjlist g2[])
{
int i,j;
edgenode *p;
for(i=0;i<g1.vexn;i++){
g2[i].data=g1.vertex[i];
g2[i].firstarc=NULL;
}
for(i=0;i<g1.vexn;i++){
for(j=0;j<g1.vexn;j++){
if(g1.edge[i][j]==1){
p=(edgenode*)malloc(sizeof(edgenode));
p->adjvertex=j;
p->nextarc=g2[i].firstarc;
g2[i].firstarc=p;
p=(edgenode*)malloc(sizeof(edgenode));
p->adjvertex=i;
p->nextarc=g2[j].firstarc;
g2[j].firstarc=p;
}
}
}
}
六、查找
1、设计在顺序有序表中实现二分查找的算法。
struct record{int key;};
void bisearch(struct record r[], int n, int k)
{
int low=0,high=n-1;
int mid;
while(low<=high){
mid=(low+high)/2;
if(r[mid]==k) return mid+1;
else if(k < r[mid]) high=mid-1;
else low=mid+1;
}
return 0;
}
2、设计在二叉排序树上查找结点X的算法。
//非递归
bitree *bstsearch(bitree *bt,int x)
{
bitree*p=bt;
while(p){
if(x==p->data) return p;
if(x<p->data) p=p->lchild;
else p=p->rchild;
}
return 0;
}
七、排序
1、对一整型数组b[n]中的元素进行重新排列,将所有负数均调整到数组的低下标端,将所有正数均调整到数组的高下标端,若有零值,则置于两者之间,并返回数组中零元素的个数。
//调整整数数组中的元素顺序,并返回分界值i,使得所有小于x的数都在i左边,所有大于等于x的数都在i右边。
int arrange(int a[], int l ,int h, int x) //l,h分别为数据区的下界和上界
{
int i,j,t;
i=l, j=h;
while(i<j){
while(i<j && a[j]>=x) j--;
while(i<j && a[i]<=x) i++;
if(i<j){
t=a[j]; a[j]=a[i]; a[i]=t;
}
}
if(a[i]<x) return i;
else return i-1;
}
int Rearrange_Countzero(int b[],int n)
{
int p=arrange(b, 0, n-1, 0); //p位置左边全为负数
int q=arrange(b, p+1, n-1 ,1); //q位置右边全为正数
return q-p; //p和q中间都为0,q-p即为零元素个数
}
//或者
/*
int Rearrange_Countzero(int b[],int n)
{ int p=arrange(b, 0, n-1, 1); //p位置左边全为0和负数
int q=arrange(b, 0, p, 0); //q位置左边全为负数
return p-q; //p和q之间全为0,p-q即为零元素个数
}
*/
2、设有一组初始记录关键字序列(K1,K2,…,Kn),要求设计一个算法能够在O(n)的时间复杂度内将线性表划分成两部分,其中左半部分的每个关键字均小于Ki,右半部分的每个关键字均大于等于Ki。
void quickpass(int r[], int start, int end)
{
int i=start,j=end,x=r[start];
while(i<j){
while(i<j && r[j]>x) j--;
if(i<j) {r[i]=r[j]; i++;}
while(i<j && r[i]<x) i++;
if(i<j) {r[j]=r[i]; j--;}
}
r[i]=x;
}
3、 在链式存储结构上设计直接插入排序算法。
void InsertSort(lklist *&head)
{
lklist *s,*p,*q;
int t;
if(head==0 || head->next==0) return;
else for(q=head,p=head->next; p!=0; p=q->next){
for(s=head; s!=q->next; s=s->next){
if(s->data > p->data) break;
}
if(s==q->next) q=p;
else{
q->next=p->next;
p->next=s->next;
s->next=p;
t=p->data; p->data=s->data; s->data=t;
}
}
}
//法二
void InsertSort(lklist *&head)
{
lklist *p,*pre,*q;
p=head->next->next; //保存链表中第二个元素
head->next->next=NULL; //构造有序区,只有表中第一个元素
while(p!=NULL){ //从表中第二个元素开始遍历
q=p->next; //用q保存p的下一个元素
pre=head; //pre指向有序区
while(pre!=NULL && pre->next->data <= p->data) //遍历有序区直至找到比p大的结点
pre=pre->next;
p->next=pre->next;
pre->next=p;
p=q;
}
}
4、设计在链式结构上实现简单选择排序算法。
void SelectSort(lklist *&head)
{
lklist *p,*q,*s;
int min,t;
if(head==0 || head->next==0) return;
for(q=head; q!=0; q=q->next){
min=q->data;
s=q;
for(p=q->next; p!=0; p=p->next){
if(p->data < min){
min=p->data;
s=p;
}
}
if(s!=q){
t=s->data; s->data=q->data; q->data=t;
}
}
}
5、设计将所有奇数移到所有偶数之前的算法。
void quickpass(int r[],int s,int t)
{
int i=s,j=t, x=r[s];
while(i<j){
while(i<j && r[j]%2==0) j--;
if(i<j) {r[i]=r[j]; i++;}
while(i<j && r[i]%2!=0) i++;
if(i<j) {r[j]=r[i]; j--;}
}
r[i]=x;
}
6、设计在链式存储结构上合并排序的算法。
void mergesort(lklist *ha,lklist *hb.lklist *&hc)
{
lklist *s=hc=0;
while(ha!=0 && hb!=0){
if(ha->data < hb->data){
if(s==0) hc=s=ha;
else {s->next=ha; s=ha;}
ha=ha->next;
}
else{
if(s==0) hc=s=hb;
else {s->next=hb; s=hb;}
hb=hb->next;
}
}
if(ha!=0) s->next=ha;
else s->next=hb;
}
7、设关键字序列(k1,k2,…,kn-1)是堆,设计算法将关键字序列(k1,k2,…,kn-1,x)调整为堆。
void adjustheap(int r[].int n)
{
int j=n,i=j/2;
int temp=r[j-1]; //temp为最后一层的最后一个叶子,即插入的x
while(i>=1){
if(temp>=r[i-1]) break; //小根堆
else {
r[j-1]=r[i-1];
j=i;
i=i/2;
}
}
r[j-1]=temp;
}