数据结构第二章程序题1:链表合并
# include <stdio.h>
# include <stdlib.h>
typedef struct listNode {
int data;
listNode* next;
} listNode;
listNode* init_list(listNode* head,int size) {
listNode* tail=head;
for(int i=0; i<size; i++) {
// 建立新的节点并读值存值
listNode* cur=(listNode*)malloc(sizeof(listNode));
scanf("%d",&cur->data);
// 尾插
cur->next=tail->next;
tail->next=cur;
tail=tail->next;
}
return head;
}
listNode* merge_list(listNode* headA,listNode* headB) { // AB均为升序序列
listNode* p=headA;
listNode* q=headB;
listNode* movea=headA->next;
listNode* moveb=headB->next;
free(p);
free(q);
listNode* headnew=(listNode*)malloc(sizeof(listNode));
headnew->data=0;
headnew->next=NULL;
listNode* cur=headnew;
while(movea && moveb) {
if(movea->data == moveb->data) { // 将movea和moveb都并入
cur->next=movea;
movea=movea->next;
cur->next->next=moveb;
moveb=moveb->next;
cur=cur->next->next;
} else if(movea->data < moveb->data) { // 将ma并入
listNode* tmp=movea;
movea=movea->next;
tmp->next=cur->next;
cur->next=tmp;
cur=cur->next;
} else {
listNode* tmp=moveb;
moveb=moveb->next;
tmp->next=cur->next;
cur->next=tmp;
cur=cur->next;
}
}
if(movea)cur->next=movea;
if(moveb)cur->next=moveb;
return headnew;
}
listNode* reverse_list(listNode* head) {
if(!head || !head->next)return head;
listNode* tail=reverse_list(head->next);
head->next->next=head;
head->next=NULL;
return tail;
}
int main(void) {
int cnta,cntb;
scanf("%d%d",&cnta,&cntb);
listNode* headA=(listNode*)malloc(sizeof(listNode));
headA->data=0;
headA->next=NULL;
headA=init_list(headA,cnta);
listNode* headB=(listNode*)malloc(sizeof(listNode));
headB->data=0;
headB->next=NULL;
headB=init_list(headB,cntb);
listNode* headC=merge_list(headA,headB);
listNode* res=reverse_list(headC->next);
free(headC);
for(listNode* move=res; move->data; move=move->next)
printf("%d ",move->data);
listNode* p=res;
for(int i=0;i<cnta+cntb;i++)
{
res=res->next;
free(p);
p=res;
}
return 0;
}
假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的队列初始化、入队列和出队列的算法。
先输入要入队列的元素个数,输入相应的元素,输入要出队列的元素个数,最后将队列输出。
输入:
5
1 2 3 4 5
3
输出:
4 5
# include <stdio.h>
# include <stdlib.h>
# include <limits.h>
typedef struct Node {
int data;
Node* next;
} Node;
typedef struct queue {
Node head;
Node* tail;
} queue;
void init_queue(queue &q) {
q.tail=&q.head;
q.head.next=q.tail;
q.head.data=INT_MIN;
}
void push(queue &q,int e) {
Node* t=(Node*)malloc(sizeof(Node));
t->data=e;
t->next=q.tail->next;
q.tail->next=t;
q.tail=q.tail->next;
}
int pop(queue &q) {
Node* h=&q.head;
Node* res=h->next;
h->next=res->next;
if(res->next->data==INT_MIN)q.tail=&q.head;
int val=res->data;
free(res);
return val;
}
int main(void) {
int size;
scanf("%d",&size);
queue mq;
init_queue(mq);
int x;
for(int i=0; i<size; i++) {
scanf("%d",&x);
push(mq,x);
}
int cnt_pop;
scanf("%d",&cnt_pop);
for(int i=0; i<cnt_pop; i++)pop(mq);
int k=size-cnt_pop;
for(int i=0; i<k; i++) {
int val=pop(mq);
printf("%d ",val);
}
return 0;
}
用栈和队列判断回文:
# include <stdio.h>
# include <stdlib.h>
# define SIZE 50
//栈用顺序存储结构,
typedef struct {
char* base;
char* top;
int size;
} stack;
bool init_stk(stack &s) {
s.base=(char*)malloc(sizeof(char)*SIZE);
if(!s.base)return false;
s.top=s.base;
s.size=SIZE;
return true;
}
void push_stk(stack &s,char e) {
*s.top=e;
s.top++;
}
char get_top_pop_stk(stack &s) {
if(s.top!=s.base) {
s.top--;
return *s.top;
}
}
void destory_stk(stack &s) {
free(s.base);
}
//队列用链式存储结构
typedef struct Node {
char e;
Node* next;
} Node;
typedef struct {
Node* front;
Node* tail;
} Q;
void init_q(Q &q) {
q.front=(Node*)malloc(sizeof(Node));
q.tail=q.front;
q.front->e=0;
q.front->next=NULL;
}
void en_q(Q &q,char c) {
Node* qnew=(Node*)malloc(sizeof(Node));
qnew->e=c;
qnew->next=NULL;
q.tail->next=qnew;
q.tail=q.tail->next;
}
char de_pop_q(Q &q) {
char c=q.front->next->e;
Node* t=q.front->next;
q.front->next=q.front->next->next;
free(t);
return c;
}
int main(void) {
stack stk;
init_stk(stk);
Q myq;
init_q(myq);
int cnt=0;
char op[50];
gets(op);
for(int i=0; op[i]!='@'; i++) {
cnt++;
push_stk(stk,op[i]);
en_q(myq,op[i]);
}
bool flag=true;
char a,b;
for(int i=0; i<cnt; i++) {
a=get_top_pop_stk(stk);
b=de_pop_q(myq);
if(a!=b)flag=false;
printf("%c",b);
}
if(flag)puts("是回文");
else puts("不是回文");
destory_stk(stk);
return 0;
}
编写递归算法,在二叉树中求位于先序序列中第k个位置的结点的值(请严格按照样例进行输入输出,先输入二叉树树,再输入k的值)。
样例如下:
输入:ABD..EH...CF.I..G..
5
输出:H
# include <stdio.h>
# include <stdlib.h>
char op[50];
typedef struct BiTNode {
char data;
struct BiTNode *lchild,*rchild;
} node;
void creat_biTree(node* &t,int& u) {
//printf("-----%c----\n",op[u]);
if(op[u]) {
if(op[u]=='.')t=nullptr;
else {
t=(node*)malloc(sizeof(node));
t->data=op[u];
//printf("-----%c----\n",t->data);
u++;
creat_biTree(t->lchild,u);
u++;
creat_biTree(t->rchild,u);
}
}
}
char preorder(node* &t,int k,int& cnt) {
if(t) {
cnt++;
//printf("-----%d----\n",cnt);
if(cnt==k) {
return t->data;
}
char c=preorder(t->lchild,k,cnt);
if(c)return c;
c=preorder(t->rchild,k,cnt);
if(c)return c;
}
}
void freet(node* &t) {
if(t) {
node* l=t->lchild;
node* r=t->rchild;
//printf("-----%c----\n",t->data);
free(t);
freet(l);
freet(r);
}
}
int main(void) {
gets(op);
int index=0;
node* root;
creat_biTree(root,index);
int k;
scanf("%d",&k);
//printf("-----%d----\n",k);
int cnt=0;
//printf("-----%d----\n",cnt);
char res=preorder(root,k,cnt);
printf("%c\n",res);
freet(root);
return 0;
}
编写递归算法,计算二叉树中叶子结点的数目(请严格按照样例进行输入输出,输入二叉树)。
样例如下:
输入:ABDF....C.E..
输出:2
# include <stdio.h>
# include <stdlib.h>
char op[50];
typedef struct BiTNode {
char data;
struct BiTNode *lchild,*rchild;
} node;
void creat_biTree(node* &t,int& u) {
//printf("-----%c----\n",op[u]);
if(op[u]) {
if(op[u]=='.')t=nullptr;
else {
t=(node*)malloc(sizeof(node));
t->data=op[u];
//printf("-----%c----\n",t->data);
u++;
creat_biTree(t->lchild,u);
u++;
creat_biTree(t->rchild,u);
}
}
}
void freet(node* &t) {
if(t) {
node* l=t->lchild;
node* r=t->rchild;
//printf("-----%c----\n",t->data);
free(t);
freet(l);
freet(r);
}
}
void cnt_leaf(node* &t,int &sum) {
//printf("-----%c----\n",t->data);
if(!t)return;
if(!t->lchild && !t->rchild) {
sum++;
//printf("-----%d----\n",sum);
return;
} else {
cnt_leaf(t->lchild,sum);
cnt_leaf(t->rchild,sum);
}
}
int main(void) {
gets(op);
int index=0;
//printf("-----%s----\n",op);
node* root;
creat_biTree(root,index);
//printf("-----%d----\n",index);
int sum=0;
cnt_leaf(root,sum);
printf("%d\n",sum);
freet(root);
return 0;
}
dfs遍历图:
# include <stdio.h>
typedef struct arcNode {
int adjvex; //边的终节点
struct arcNode *nextarc; //下一条始结点的出边
} arcNode;
typedef struct vNode {
int data; //节点编号
arcNode* firstarc; //输入数据中第一条出边
} vNode;
typedef struct {
vNode list[50]; //头节点列表
int vexnum,arcnum;
} graph;
bool st[50];
bool dfs(int start,int end,graph& g) {
st[start]=true;
if(start==end)return true;
if(g.list[start].firstarc==NULL)return false;
for(arcNode* q=g.list[start].firstarc; q!=NULL; q=q->nextarc) {
if(!st[q->adjvex] && dfs(q->adjvex,end,g))return true;
}
st[start]=false;
return false;
}
int main(void) {
graph g;
scanf("%d%d",&g.vexnum,&g.arcnum);
arcNode arc[g.arcnum*g.arcnum+10];
int k=0;
for(int i=0; i<50; i++)g.list[i].firstarc=NULL;
for(int i=0; i<g.arcnum; i++) {
int a,b;
scanf("%d%d",&a,&b);
g.list[a].data=1;
arc[k].adjvex=b;
arc[k].nextarc=NULL;
arcNode* p=g.list[a].firstarc;
if(p) {
while(p->nextarc)p=p->nextarc;
p->nextarc=&arc[k];
} else {
g.list[a].firstarc=&arc[k];
}
k++;
}
int start,end;
scanf("%d%d",&start,&end);
if(dfs(start,end,g))puts("连通");
else puts("不连通");
return 0;
}
内部排序:
试以L.r[k+1]作为监视哨改写教科书10.2.1节中给出的直接插入排序算法
# include <stdio.h>
# include <iostream>
# define MAXSIZE 20
typedef int KeyType;
typedef int InfoType;
typedef struct {
KeyType key;
InfoType otherinfo;
} RedType;
typedef struct {
RedType r[MAXSIZE+1];
int length;
} SqList;
void InsertSort(SqList &q) {
int i=2;
for(i; i<=q.length; i++)
if(q.r[i].key<q.r[i-1].key) {
q.r[0].key=q.r[i].key;
q.r[i].key=q.r[i-1].key;
int j=i-2;
for(j=i-2; q.r[0].key<q.r[j].key; j--)
q.r[j+1].key=q.r[j].key;
q.r[j+1].key=q.r[0].key;
}
}
//2 4 5 8 19 25 27 32 42 47 57 64 67 68 69 87 88 99 147 559
int main(void) {
SqList q;
q.length=20;
q.r[0].key=0;
q.r[1].key=559;
q.r[2].key=147;
q.r[3].key=99;
q.r[4].key=88;
q.r[5].key=87;
q.r[6].key=69;
q.r[7].key=68;
q.r[8].key=67;
q.r[9].key=64;
q.r[10].key=57;
q.r[11].key=47;
q.r[12].key=42;
q.r[13].key=32;
q.r[14].key=27;
q.r[15].key=25;
q.r[16].key=19;
q.r[17].key=8;
q.r[18].key=5;
q.r[19].key=4;
q.r[20].key=2;
InsertSort(q);
for(int i=1; i<=q.length; i++)
printf("%d ",q.r[i].key);
return 0;
}
编写算法,对n nn个关键字取整数值的记录序列进行整理,以使所有关键字为负值为记录排在关键字为非负的记录之前,要求:
(1)采用顺序存储结构,至多使用一个记录的辅助空间;
(2)算法的时间复杂度为O ( n )
(3) 讨论算法的最大移动次数
该用例使用数组为:9, 18, -5, 0, -9, 28, 2, -9, 0,-7, 6, 13
算法最大移动次数为(n/2)
输出正确结果为:9, 18, -5, 0, -9, 28, 2, -9, 0,-7, 6, 13
试以单链表为存储结构实现简单选择排序算法(升序)
# include <stdio.h>
# include <stdlib.h>
typedef struct Node {
int key;
Node* next;
} Node;
typedef struct List {
Node* head;
Node* tail;
} List;
//void swap(Node* l,Node* a,Node* b)
//{
// Node* a1=(Node*)malloc(sizeof(Node));
// a1->key=a->key;
// Node* b1=(Node*)malloc(sizeof(Node));
// b1->key=b->key;
//
// Node* fa;
// Node* fb;
// bool has_fa=0,has_fb=0;
// for(Node* find=l;find;find=find->next)
// {
// printf("++++++++++++++\n");
// printf("%d\n",find->key);
// if(!has_fa && find->next==a)
// {
// printf("_______________\n");
// has_fa=true;
// printf("$$%d\n",has_fa);
// fa=find;
// fa->next=fa->next->next;
// free(a);
// }
//
// if(!has_fb && find->next==b)
// {
// printf("==============\n");
// has_fb=true;
// printf("$$%d\n",has_fb);
// fb=find;
// fb->next=fb->next->next;
// free(b);
// }
//
// if(has_fa && has_fb)
// {
// printf("*************\n");
// break;
// }
// }
// printf("&&&&&&&&&&\n");
//
// b1->next=fa->next;
// fa->next=b1;
//
// a1->next=fb->next;
// fa->next=a1;
//}
int main(void) {
int cnt;
scanf("%d",&cnt);
List l;
l.head=l.tail=(Node*)malloc(sizeof(Node));
scanf("%d",&l.head->key);
l.tail->next=NULL;
for(int i=1; i<cnt; i++) {
Node* data=(Node*)malloc(sizeof(Node));
scanf("%d",&data->key);
data->next=l.tail->next;
l.tail->next=data;
l.tail=l.tail->next;
}
Node* lc;
for(lc=l.head; lc!=l.tail; lc=lc->next) {
Node* min=lc;
for(Node* j=lc->next; j; j=j->next) {
if(j->key<min->key) {
min=j;
}
}
if(min!=lc) {
int tmp=min->key;
min->key=lc->key;
lc->key=tmp;
// swap(lc,min,lc);
}
}
for(Node* st=l.head; st; st=st->next) {
printf("%d ",st->key);
}
return 0;
}
//未完