记录本人在数据结构课程中遇到的编程练习题,方便需要时查阅
目录
单链表的创建
【问题描述】从键盘终端输入若干整数,为其创建带头节点的单链表存储结构
【样例输入】
5
12 23 32 33 45
【样例输出】12 23 32 33 45
【样例说明】第一行的数为单链表中元素的个数,后面为各元素的值
#include <iostream>
using namespace std;
struct LNode {
int data;
LNode *next;
};
typedef LNode *LinkList;
//------------尾插法创建单链表---------------
void createList(LinkList &h,int n) {
h=new LNode;
h->next=NULL;
LinkList p=h;
for(int i=0; i<n; i++) {
p->next=new LNode;
cin>>p->next->data;
p=p->next;
}
p->next=NULL;
}
//--------------------------------------------
void printList(LinkList h) {
LNode *p;
p=h->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int main() {
LinkList h;
int n;
cin>>n;
createList(h,n);
printList(h);
return 0;
}
顺序表的插入
【问题描述】某顺序表中存放着若干整数,请根据上下文,将整数num插入到顺序表的第i个位置上。如果插入位置不对,输出"position error!",并终止程序的执行。
【输入形式】三行,第一行:顺序表中元素个数,第二行:顺序表中的数据元素;第三行:插入的元素和插入的位置以空格间隔
【输出形式】插入后的顺序表中的数据元素以空格间隔输出
【样例输入】
5
1 2 3 4 5
3 10
【样例输出】1 2 10 3 4 5
#include <iostream>
#include <cstdlib>
using namespace std;
struct SqList {
int *elem;
int length;
int listsize;
};
void initList(SqList &L,int n) {
L.elem=(int *)malloc(sizeof(int)*n);
if(L.elem==NULL) {
cout<<"overflow";
exit(0);
}
L.length=0;
L.listsize=n;
}
void add(SqList&L,int x) {
if(L.length>=L.listsize) {
int *base;
base=(int *)realloc(L.elem,sizeof(int)*(L.listsize+10));
if(base==NULL) {
cout<<"overflow";
exit(0);
}
L.elem=base;
L.listsize+=10;
}
L.elem[L.length]=x;
L.length++;
}
//---------------向第i个位置插入元素-----------------
void listInsert(SqList &L,int i,int num) {
if(i<1||i>L.length+1) {
cout<<"position error!";
exit(0);
}
int *q=&(L.elem[i-1]);
for(int* p=&(L.elem[L.length-1]); p>=q; p--)
*(p+1)=*p;
*q=num;
L.length++;
}
//-----------------------------------------
void printList(SqList L) {
for(int i=0; i<L.length; i++) {
cout<<L.elem[i]<<" ";
}
cout<<"\n";
}
int main() {
SqList L;
int n,num,i;
int e;
cin>>n;
initList(L,n);
for(int j=1; j<=n; j++) {
cin>>e;
add(L,e);
}
cin>>i>>num;
listInsert(L,i,num);
printList(L);
return 0;
}
输出单链表倒数第k个元素
【问题描述】已知带头结点的非空单链表中存放着若干整数,请找出该链表中倒数第k个元素。
【输入形式】第一行:单链表中元素个数m,第二行:单链表中的m个整数,第三行:k值
【输出形式】倒数第k个元素的值(不存在倒数第k个元素输出"no")
【样例1】
输入 :
5
13 24 50 33 56
2
输出: 33
【样例2】
输入:
5
13 24 50 33 56
6
输出:no
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
typedef Node *LinkList;
void createList(LinkList &L,int n) {
Node *p,*r;
L=new Node;
L->next=NULL;
r=L;
for(int i=1; i<=n; i++) {
p=new Node;
cin>>p->data;
r->next=p;
r=p;
}
r->next=NULL;
}
void printList(LinkList L) {
Node *p;
p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
//------找单链表中倒数第k个元素-------
Node* getElem(LinkList L,int k) {
LinkList p=L;
int length=0;
while(p->next) {
length++;
p=p->next;
} //获取单链表的长度
p=L;
if(length-k<0) return NULL; //不存在倒数第k个元素
for(int i=0; i<length-k+1; i++) //倒数第k个元素,即为顺数的length-k+1个元素
p=p->next;
return p;
}
//--------------------------------
int main() {
LinkList L;
int m,k;
cin>>m; //单链表中元素个数
createList(L,m); //尾插入法创建带头节点的单链表
cin>>k;
Node *p=getElem(L,k); //找单链表中倒数第k个元素
if(p)
cout<<p->data;
else
cout<<"no";
return 0;
}
创建有序单链表
【问题描述】为从键盘终端输入的m个整数创建带头结点的有序单链表存储结构,使输入的数据元素在单链表中按照元素值递增有序。
【输入形式】
第一行:单链表中元素个数m
第二行:单链表中的m个整数
【输出形式】按递增有序形式输出m个整数
【样例输入】
5
1 3 2 4 5
【样例输出】1 2 3 4 5
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
typedef Node *LinkList;
//-----------创建有序单链表-------
void createOList(LinkList &h,int n) {
Node *p,*pre;
h=new Node;
h->next=NULL;
for(int i=1;i<=n;i++){
p=new Node;
cin>>p->data;
pre=h;
while(pre->next && pre->next->data < p->data){
pre=pre->next;
} //边比较边插入
p->next=pre->next;
pre->next=p;
}
}
//----------------------
void printList(LinkList L) {
Node *p;
p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int main() {
LinkList L;
int m;
cin>>m;//单链表中元素个数
createOList(L,m);//创建带头节点的有序单链表
printList(L);
return 0;
}
输出单链表中的数据并统计单链表中的元素个数
【问题描述】下面程序中createList函数的功能是创建若干个整数的带头结点的单链表存储结构。
getLength函数的功能是求解单链表中元素的个数,printLst函数的功能是将单链表中各个整数以空格间隔顺序输出。
【输入形式】若干整数以空格间隔
【输出形式】两行。第一行:单链表中的整数以空格间隔输出;第二行:单链表中元素的个数
【样例输入】1 2 3 4 5
【样例输出】
1 2 3 4 5
5
#include <iostream>
#include <cstdlib>
using namespace std;
struct LNode {
int data;
LNode *next;
};
void createList(LNode *&h) {
int num;
LNode *p,*r;
h=new LNode;
h->next=NULL;
r=h;
while(cin>>num) {
p=new LNode;
p->data=num;
r->next=p;
r=p;
}
r->next=NULL;
}
//----------------------------
void printList(LNode* L) {
LNode* p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<"\n";
}
int getLength(LNode* L) {
LNode* p=L->next;
int count=0;
while(p) {
count++;
p=p->next;
}
return count;
}
//----------------------------
int main() {
LNode *L;
createList(L);
printList(L);
cout<<getLength(L);
return 0;
}
删除单链表中相同元素
【问题描述】单链表中存放了若干整数,请删除相同整数。
【输入形式】单链表
【输出形式】删除相同整数后的单链表
【样例输入】1 1 1 2 3
【样例输出】1 2 3
【样例说明】递增的形式输入数据,允许相同元素
#include <stdlib.h>
#include <iostream>
using namespace std;
struct LNode {
int data;
LNode *next;
};
typedef LNode *LinkList;
void createList(LinkList &h, int n) {
h = new LNode;
h->next = NULL;
LNode *p, *r;
r = h;
for (int i = 1; i <= n; i++) {
p = new LNode;
cin>>p->data;
r->next = p;
r = p;
}
r->next = NULL;
}
void printList(LinkList h) {
LNode *p=h->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
//---------------
void listDeleteRepeat(LinkList &h) {
LinkList p=h->next;
while(p->next) {
if(p->data==p->next->data)
p->next=p->next->next;
else
p=p->next;
}
}
//---------------
int main() {
LinkList h;
createList(h, 5);
listDeleteRepeat(h);
printList(h);
return 0;
}
删除单链表中某区间的数
【问题描述】已知某带头结点的单链表中存放着若干整数,请删除该单链表中元素在[x, y]之间的所有结点,
要求算法的时间复杂度为O(n),空间复杂度为O(1)。
【输入形式】
第一行:单链表中元素个数m
第二行:单链表中的m个整数
第三行:要删除的元素值所在区间[x,y]对应的x和y
【输出形式】除元素后的单链表中剩下的元素值
【样例输入】
5
13 24 50 33 56
30 50
【样例输出】13 24 56
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
typedef Node *LinkList;
void createList(LinkList &L,int n) {
Node *p,*r;
L=new Node;
L->next=NULL;
r=L;
for(int i=1; i<=n; i++) {
p=new Node;
cin>>p->data;
r->next=p;
r=p;
}
r->next=NULL;
}
void printList(LinkList L) {
Node *p;
p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
//----------------------------
void delElem(LinkList L, int x, int y) {
Node *p,*q;
p=L;
while(p->next) {
if(p->next->data>=x&&p->next->data<=y) {
q=p->next;
p->next=q->next;
delete q;
} else {
p=p->next;
}
}
}
//----------------------------
int main() {
LinkList L;
int m;
int x,y;
cin>>m;//单链表中元素个数
createList(L,m);//尾插入法创建带头节点的单链表
cin>>x>>y;//要删除的元素值所在区间[x,y],包含x和y
delElem(L,x,y);//删除单链表中x-y之间的数
printList(L);//输出结果单链表中的所有数据
return 0;
}
链式栈的设计与实现
【问题描述】采用链式存储结构实现栈的基本操作,并借助栈实现进制转换。
【输入形式】整数
【输出形式】二进制数
【样例输入】10
【样例输出】1010
#include <iostream>
using namespace std;
#include <stdlib.h>
struct snode{
int data;
snode *next;
};
typedef snode *linkstack;
//----链式栈的基本操作----
void initStack(linkstack &top){
top=new snode;
top->next=NULL;
}//初始化,创建带头结点的链式栈
void push(linkstack &top,int e){
linkstack p;
p=new snode;
p->data=e;
p->next=top->next;
top->next=p;
}//进栈
bool stackEmpty(linkstack top){
if(top->next==NULL)
return true;
else
return false;
}//判断栈是否空
int pop(linkstack &top){
int e=top->next->data;
top->next=top->next->next;
return e;
}//出栈
void pop(linkstack &top,int &e){
e=top->next->data;
top->next=top->next->next;
}//出栈,通过e带出栈顶元素
int getTop(linkstack top){
return top->next->data;
}//获取栈顶元素
//----------------------
//----借助栈实现十进制转换二进制----
void converse(int m,linkstack &s){
initStack(s);
if(m==0) push(s,m);
else
while(m){
push(s,m%2);
m=m/2;
}
}
//-----------------------
int main(){
linkstack s;
int m;
cin>>m;
converse(m,s);
while(!stackEmpty(s)){
cout<<pop(s);
}
return 0;
}
顺序栈的基本操作
【问题描述】按照要求完成顺序栈的设计
【输入形式】无
【输出形式】20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <stdio.h>
#define STACKSIZE 10
#define INCRE 2
struct sqstack{
int *base;
int top;
int stacksize;
};
//-----顺序栈的基本操作------
void initStack(sqstack &s){
s.base=(int*)malloc(STACKSIZE*sizeof(int));
s.top=0;
s.stacksize=STACKSIZE;
}//顺序栈的初始化
bool stackEmpty(sqstack s){
return s.top==0;
}//判断栈是否空
bool stackFull(sqstack s){
return s.top>=s.stacksize;
}//判断栈是否满
void push(sqstack &s,int e){
if(stackFull(s)){
s.base=(int*)realloc(s.base,(s.stacksize+INCRE)*sizeof(int));
s.stacksize+=INCRE;
}
s.base[s.top++]=e;
}//进栈
int pop(sqstack &s){
s.top--;
return s.base[s.top];
}//出栈
int gettop(sqstack &s){
return s.base[s.top];
}//获取栈顶元素
//-----------------------
int main(){
sqstack s;
initStack(s);
for(int i=1;i<=20;i++){
push(s,i);
}//1~20顺序进栈
while(!stackEmpty(s)){
cout<<pop(s)<<" ";
}
}
回文链表
【问题描述】给你一个带头结点的单链表,请你编写函数isPalindrome,判断该链表是否为回文链表。
如果是,返回true;否则,返回false。
其中函数createList,采用尾插入法创建含有头结点的单链表。
【输入形式】两行,第一行:单链表中元素个数n,第二行:以空格间隔的n个整数
【输出形式】单链表是回文链表,输出yes,否则输出no
【样例输入】
4
1 2 2 1
【样例输出】yes
【样例输入】
6
1 2 2 2 1 2
【样例输出】no
#include <iostream>
#include <stdlib.h>
using namespace std;
struct Node {
int data;
Node *next;
};
void createList(Node *&h,int n) {
Node *p,*r;
h=new Node;
h->next=NULL;
r=h;
for(int i=1; i<=n; i++) {
p=new Node;
cin>>p->data;
r->next=p;
r=p;
}
r->next=NULL;
}//尾插法创建带头结点的单链表
void printList(Node *h) {
Node *p;
p=h->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}//输出单链表元素
//------借助栈,判断链表元素是否构成回文-------
typedef struct {
int* base;
int* top;
} sqstack;
void initStack(sqstack &s) {
s.base=(int*)malloc(10*sizeof(int));
s.top=s.base;
}//顺序栈的初始化
void push(sqstack &s,int e) {
*s.top++=e;
}//进栈
void pop(sqstack &s,int &e) {
e=*--s.top;
}//出栈
int isEmpty(sqstack s) {
if(s.top==s.base) return 1;
else return 0;
}//判断是否为空
int getLength(Node* h) {
Node* p=h;
int count=0;
while(p->next) {
count++;
p=p->next;
}
return count;
}//获取链表中元素数量
int isPalindrome(Node *h) {
Node *p=h->next;
sqstack s;
initStack(s);
for(int i=0; i<getLength(h); i++) {
push(s,p->data);
p=p->next;
}//链表元素入栈
p=h->next;
int e;
while(!isEmpty(s)) {
pop(s,e);
if(e==p->data) p=p->next;
//出栈,比较下一个数字
else return 0;
//若某次比较失败,返回0,不是回文链表
}
return 1;//全部比较成功,是回文链表
}
//--------------------------------
int main() {
int n;
Node *h;
cin>>n;
createList(h,n);
cout<<(isPalindrome(h)?"yes":"no");
return 0;
}
链式队列的基本操作
【问题描述】根据链式队列的类型定义,完成链队列的基本操作。主函数中测试队列。
【输入形式】一个整数m,表示入队的元素个数
【输出形式】第一行:输出队头元素 第二行:队列中元素依次出队以空格间隔
【样例输入】5
【样例输出】
1
1 3 5 7 9
【样例输入】0
【样例输出】empty!
#include <iostream>
using namespace std;
#include <stdlib.h>
struct QNode {
int data;
QNode *next;
};
struct LinkQueue {
QNode *front;
QNode *rear;
};
//---------------------
void initQueue(LinkQueue &Q) {
Q.front=Q.rear=(QNode *)malloc(sizeof(QNode));
}//初始化
void enQueue(LinkQueue &Q,int n) {
QNode *p=(QNode *)malloc(sizeof(QNode));
p->data=n;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}//进队列
int queueEmpty(LinkQueue Q) {
if(Q.front==Q.rear) return 1;
else return 0;
}//判断队列是否为空
int deQueue(LinkQueue &Q) {
if(!queueEmpty(Q)) {
int e=Q.front->next->data;
Q.front=Q.front->next;
return e;
}
}//出队列
int getFront(LinkQueue Q) {
if(!queueEmpty(Q)) {
return Q.front->next->data;
}
else {
cout<<"empty!";
exit(0);
}
}//获取队头元素,若为空队列,输出empty!并结束程序
//------------------------
int main() {
int m;
cin>>m;
LinkQueue Q;
initQueue(Q);
for(int i=1; i<=m; i++) {
enQueue(Q,i*2-1);
}
cout<<getFront(Q)<<endl;
while(!queueEmpty(Q)) {
cout<<deQueue(Q)<<" ";
}
}
循环队列的基本操作
【问题描述】根据循环队列的类型定义,完成循环队列的基本操作。主函数中测试队列。
【输入形式】一个整数m,表示入队的元素个数
【输出形式】第一行:输出队头元素 第二行:队列中元素依次出队以空格间隔
【样例输入】5
【样例输出】
1
1 3 5 7 9
【样例输入】0
【样例输出】empty!
#include <iostream>
using namespace std;
#include <stdlib.h>
#define MAX 100
struct circleQueue {
int data[MAX];
int front,rear;
int count;
};
//----------------------
void initQueue(circleQueue &Q){
Q.front=Q.rear=0;
Q.count=0;
}//初始化
void enQueue(circleQueue &Q,int n){
Q.data[Q.rear]=n;
Q.rear++;
Q.count++;
}//进队列
int queueEmpty(circleQueue Q){
return Q.count==0;
}//判断是否为空
int getFront(circleQueue Q){
if(!queueEmpty(Q))return Q.data[Q.front];
else {
cout<<"empty!";
exit(0);
}
}//获取队首元素,若为空,输出empty!并结束程序
int deQueue(circleQueue &Q){
int e=Q.data[Q.front];
Q.front++;
Q.count--;
return e;
}//出队列
//----------------------
int main() {
int m;
cin>>m;
circleQueue Q;
initQueue(Q);
for(int i=1; i<=m; i++) {
enQueue(Q,i*2-1);
}
cout<<getFront(Q)<<endl;
while(!queueEmpty(Q)) {
cout<<deQueue(Q)<<" ";
}
}
求解由单链表表示的一元多项式的值
【问题描述】一个形如
a 0 x 0 + a 1 x 1 + . . . + a n x n a_0x^0+a_1x^1+...+a_nx^n a0x0+a1x1+...+anxn
的一元多项式含有n+1项,每一项由系数和指数唯一确定,可表示成由系数项和指数项构成的一个二元组(系数,指数),一元多项式则可以表示成二元组的集合{(a0,0),(a1,1),(a2,2)…(an,n)},可看成是数据元素为二元组(系数,指数)的线性表,若将某一个一元多项式的二元组集合采用链式存储结构存储于带头结点的单链表中,请根据给定的x值,求解一元多项式的值。
例如:
A ( x ) = 3 x 2 − 4 x 6 + 6 x 8 + 10 x 9 A(x)=3x^2-4x^6+6x^8+10x^9 A(x)=3x2−4x6+6x8+10x9
可表示成{(3,2),(-4,6),(6,8),(10,9)},含有4个元素的线性表
下列的createPolyList函数,用于创建含有n项的一元多项式的带头结点的单链表存储结构,
getValue函数则根据给定的一元多项式L和x值,求解并返回一元多项式的值。
请将程序补充完整。
【输入形式】
第一行:一元多项式的项数
第二行:一元多项式的每一项的系数项和指数项,中间用空格间隔
第三行:一元多项式的x的取值
【输出形式】计算结果
【样例输入】
4
3 2 -4 6 6 8 10 9
1
【样例输出】15
#include <iostream>
#include <cstdlib>
using namespace std;
struct PolyNode {
double coef;//系数
int exp;//次数
};
struct LNode {
PolyNode data;
LNode *next;
};
typedef LNode *LinkList;
void createPolyList(LinkList &L,int n) {
L=new LNode;
L->next=NULL;
LNode *r,*p;
r=L;
for(int i=1; i<=n; i++) {
p=new LNode;
cin>>p->data.coef>>p->data.exp;
r->next=p;
r=p;
}
r->next=NULL;
}
//------以下为参考答案------
double getValue(LinkList L,double x){
double value=0,t;
LNode *p;
p=L->next;
while(p){
t=p->data.coef;
for(int j=1; j<=p->data.exp; j++)
t=t*x;
value+=t;
p=p->next;
}
return value;
}
//---------------------
int main() {
LinkList L;
int n;//多项式的项数
double x;
cin>>n;
createPolyList(L,n);
cin>>x;
cout<<getValue(L,x);
return 0;
}
记录一些数据结构学习过程的习题代码,便于日后查看。如有错误,欢迎交流指正。