本人总结了各个高校数据结构历年考研真题,供大家参考使用
1.(2015年全国硕士研究生计算机考研真题)用单链表保存m个整数,节点的结构为(data,link),且|data|<n(n为正整数)。现要求设计一个时间复杂度尽可能高效地算法,对于链表中绝对值相等的节点,仅保留第一次出现的节点而删除其余绝对值相等的节点。<
p=""></n(n为正整数)。现要求设计一个时间复杂度尽可能高效地算法,对于链表中绝对值相等的节点,仅保留第一次出现的节点而删除其余绝对值相等的节点。<>
例如若给定的单链表head如下
删除节点后的head为
要求
(1)给出算法的基本思想
(2)使用c或c++语言,给出单链表节点的数据类型定义。
(3)根据设计思想,采用c或c++语言描述算法,关键之处给出注释。
(4)说明所涉及算法的时间复杂度和空间复杂度。
解:
#include “stdio.h”
#include “stdlib.h”
#define M 7
typedef int ElemType;
typedef struct node
{
ElemType data;
struct node *link;
}LinkList;
int shaixuan(LinkList *p)
{
LinkList a;
int x=M;
int N=M;
int i,j,g,z=0,flag=0;
int num[M];
for(g=0;g<=N;g++)
{
a=p;z=0;
// printf(“g!\n”);
for(i=0;i<=N;i++)
{
// printf(“4!%d\n”,a->data);
if(a->link!=NULL)
{
num[z]=a->link->data;
// printf(“6,%d\n”,num[z]);
}
if(num[z]<0)
{
// printf(“7\n”);
num[z]=num[z](-1);
}
for(j=0;j<z;j++)
{
// printf(“8\n”);
if(num[z]num[j])
{
// printf(“9\n”);
flag=1;
z–;
}
}
z++;
if(flag1)
{
// printf(“11\n”);
if(a->link!=NULL)
{
// printf("!\n");
a->link=a->link->link;
}
N–;
}
flag=0;
// printf(“12!\n”);
if(a->link!=NULL)
{
a=a->link;
}
}
}
// printf(“13\n”);
return z;
}
LinkList *CreateList()
{
int i;
LinkList *head,*p,*r;
head=(LinkList *)malloc(sizeof(LinkList));
r=head;
for(i=1;i<=M;i++)
{
p=(LinkList *)malloc(sizeof(LinkList));
printf(“请输入第%d个数据”,i);
scanf("%d",&(p->data));
r->link=p;
r=p;
}
r->link=NULL;
return head;
}
void main()
{
LinkList *head;
head=CreateList();
int x=M,i;
x=shaixuan(head);
LinkList p;
p=head;
for(i=1;i<=x;i++)
{
printf(" %d “,p->link->data);
p=p->link;
}
printf(”\n");
}
2.判断链表是否有环
LinkNode judgeRing(Linklist list){
LinkNode *fast = list;
LinkNode *slow = list;
if(list == NULL)
return NULL;
while(true){
if(slow->next != NULL && fast->next != NULL && fast->next->next != NULL){
slow = slow->next;
fast = fast->next->next;
}
else
return NULL;
if(fast == slow)
return fast;
}
}
3.求有环单链表环长
int getRingLength(LinkNode *ringMeetNode){
int RingLength=0;
LinkNode *fast = ringMeetNode;
LinkNode *slow = ringMeetNode;
for(;😉{
fast = fast->next->next;
slow = slow->next;
RingLength++;
if(fast == slow)
break;
}
return RingLength;
}
4.编写程序,实现在带头结点的单链表 L 中删除一个最小值结点的算法。写出算法思想。 (2011南航)
#include <stdio.h>
#include <stdlib.h>
#ifndef NULL
#define NULL 0
#endif
typedef struct node{
int data;
struct node *next;
}node;
typedef node *LinkedList;
void Delete(LinkedList L) {
LinkedList p, pre, q;
p = L->next;
pre = L;
q = p;
while (p->next) {
if (p->next->data < q->data) {
pre = p;
q = p->next;
}
p = p->next;
}
pre->next = q->next;
free(q);
}
void add(LinkedList L, int num) {
LinkedList p = L;
while (p->next) {
p = p->next;
}
p->next = (LinkedList) malloc(sizeof(node));
p = p->next;
if § {
p->data = num;
p->next = NULL;
} else {
printf(“Memory allocation ERROR!\n”);
exit(1);
}
}
void output(LinkedList L) {
LinkedList p = L->next;
while § {
printf("%4d\t", p->data);
p = p->next;
}
printf("\n");
}
void empty(LinkedList L) {
LinkedList p = L, q;
while (p->next) {
q = p->next;
p->next = q->next;
free(q);
}
}
int main() {
LinkedList L = (LinkedList) malloc(sizeof(node));
char c;
int t;
if (L) L->next = NULL;
else return 1;
printf(“Input integers to store: \n”);
do{
scanf("%d", &t);
add(L, t);
c = getchar();
} while (c!=’\n’);
printf(“The list is: \n”);
output(L);
printf(“Delete the minimum data of the list.\n”);
Delete(L);
printf(“Delete completed!\nThen the list is: \n”);
output(L);
empty(L);
free(L);
return 0;
}
5.设 L 为带头结点的单链表,元素值为整数。设计一个算法,调整结点的位置, 将所有元素值为负数的结点移动到元素值为正数的结点之前,要求时间复杂度 T(n)=O(n)。 要求先给出算法思想,再写出相应代码。 (2012南航)
voidMoveList(SeqList &L)
{
int i=0,j=L.size-1;
while(i<j){
while(L.list[i]<=0)
i++;
while(L.list[j]>0)
j–;
if(i<j){
temp=L.list[i];
L.list[i]=L.list[j]
L.list[j]=temp;
}
}
}
设一个带头结点的单链表 L,数据元素为(a1,a2,a3,a4,… ,an),编写函数,调整该链表,使得数据元素次序为(a1, a3,…,an, … ,a4,a2), 要求 T(n)=O(n),先给出算法思想,再写出相应代码。 (2014南航)
void f(LinkList L)
{
LinkList p,h,r,s;
if(!L―>next ‖!L―>next―>next)return;
h=L―>next;
r=h;∥h和r分别为奇数结点的头、尾指针
L―>next=h―>next;
p=L―>next;∥p指向偶数结点
while(p―>next)∥2个结点以上
{
s=p―>next;∥s指向奇数结点
p―>next=s―>next;∥删除奇数结点
r―>next=s;∥链接奇数结点
r=s:
if(p―>next)
p=p―>next;∥尚有偶数结点存在
}
p―>next=h;
r―>next=NULL;
}
6.(河北工业大学803考研 2012)设计算法将一个带有头结点的单循环链表A分解为两个具有相同结构的链表B和 C,其中B表中结点为A 表中元素值为奇数的结点,而 C表中结点为A表中元素值为偶数的结点。
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
char data;
struct node *nextPtr;
}*LinkList, Lnode;
static void CreateList(LinkList *headPtr, LinkList *tailPtr, char ch);
static void Decompose(LinkList *headPtrA, LinkList *headPtrB, LinkList *tailPtrB);
static void VisitList(LinkList headPtr);
static void DestroyList(LinkList *headPtr, LinkList *tailPtr);
int main(void)
{
LinkList headPtrA = NULL, tailPtrA = NULL, headPtrB = NULL, tailPtrB = NULL;
char ch;
while (1)
{
printf(“Enter ch(’@’-quit): “);
scanf(” %c”, &ch);
if (ch == ‘@’)
{
break;
}
else
{
CreateList(&headPtrA, &tailPtrA, ch);
}
}
VisitList(headPtrA); /* 打印分解前的链表 */
if (headPtrA != NULL) /* 链表不空的情况对其进行分解 /
{
Decompose(&headPtrA, &headPtrB, &tailPtrB); / 对链表进行分解*/
}
else
{
printf(“headPtrA is empty.\n”);
}
VisitList(headPtrA); /* 打印分解后的链表 */
VisitList(headPtrB);
DestroyList(&headPtrA, &tailPtrA); /* 销毁链表 */
DestroyList(&headPtrB, &tailPtrB);
return 0;
}
static void CreateList(LinkList *headPtr, LinkList *tailPtr, char ch)
{
LinkList newPtr;
if ((newPtr = (LinkList)malloc(sizeof(Lnode))) == NULL)
{
exit(1);
}
newPtr -> data = ch;
newPtr -> nextPtr = NULL;
if (*headPtr == NULL)
{
newPtr -> nextPtr = *headPtr;
*headPtr = newPtr;
}
else
{
(*tailPtr) -> nextPtr = newPtr;
}
*tailPtr = newPtr;
}
static void Decompose(LinkList *headPtrA, LinkList *headPtrB, LinkList *tailPtrB)
{
int count = 0;
LinkList cA, pA;
char ch;
cA = NULL;
for (pA = *headPtrA; pA != NULL; cA = pA,pA = pA -> nextPtr)
{
ch = pA -> data;
count++;
if (count % 2 == 0)
{
CreateList(headPtrB, tailPtrB, ch);
cA -> nextPtr = pA -> nextPtr;
}
}
}
static void VisitList(LinkList headPtr)
{
while (headPtr != NULL)
{
printf("%c -> ", headPtr -> data);
headPtr = headPtr -> nextPtr;
}
printf(“NULL\n”);
}
static void DestroyList(LinkList *headPtr, LinkList *tailPtr)
{
LinkList tempPtr;
while (*headPtr != NULL)
{
tempPtr = *headPtr;
*headPtr = (*headPtr) -> nextPtr;
free(tempPtr);
}
*headPtr = NULL;
*tailPtr = NULL;
}
7.将递增有序的单链表A和B合并成递减有序的单链表C
实现程序如下:
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
char data; //data为结点的数据信息
struct node *next; //next为指向后继结点的指针
}LNode; //单链表结点类型
LNode *CreateLinkList() //生成单链表
{
LNode *head,*p,q;
int i,n;
head=(LNode)malloc(sizeof(LNode)); //生成头结点
head->next=NULL ;
p=head;
q=p; //指针q始终指向链尾结点
printf(“Input length of list: \n”);
scanf("%d", &n); //读入结点数据
printf(“Input data of list: \n”);
for(i=1;i<=n;i++) //生成链表的数据结点
{
p=(LNode *)malloc(sizeof(LNode)); //申请一个结点空间
scanf("%d",&p->data);
p->next=NULL;
q->next=p; //在链尾插入
q=p;
}
return head; //返回指向单链表的头指针head
}
void Merge(LNode *A,LNode B,LNode **C)
{ //将升序链表A、B合并成降序链表C
LNode p,q,s;
p=A->next; // p始终指向链表A的第一个未比较的数据结点
q=B->next; // q始终指向链表B的第一个未比较的数据结点
C=A; //生成链表的C的头结点
(C)->next=NULL;
free(B); //回收链表B的头结点空间
while(p!=NULL&&q!=NULL) //将A、B两链表中当前比较结点中值小者赋给s
{
if(p->datadata)
{
s=p;
p=p->next;
}
else
{
s=q;
q=q->next;
}
s->next=(C)->next; //用头插法将结点s插到链表C的头结点之后
(C)->next=s;
}
if(p==NULL) //如果指向链表A的指针p为空,则使p指向链表B
p=q;
while(p!=NULL) //将p所指链表中的剩余结点依次摘下插入的链表C的链首
{
s=p;
p=p->next;
s->next=(*C)->next;
(*C)->next=s;
}
}
void print(LNode *p) //输出单链表
{
p=p->next;
while(p!=NULL)
{
printf("%d,",p->data);
p=p->next;
}
printf("\n");
}
void main()
{
LNode *A,*B,*C;
printf(“Input data of list A:\n”);
A=CreateLinkList(); //生成单链表A
printf(“Output list A:\n”);
print(A); //输出单链表A
printf(“Input data of list B:\n”);
B=CreateLinkList(); //生成单链表B
printf(“Output list B:\n”);
print(B); //输出单链表B
printf(“Make list C:\n”);
Merge(A,B,&C); //将升序链表A、B合并成降序链表C
printf(“Output list C:\n”);
print©; //输出单链表C
}
:
8.(上海交通大学 考研真题1)已知一个带有表头节点的单链表,结点结构为data|next 假设该链表只给出了头指针head。在不改变链表的前提下,设计一个尽可能高效的算法,查找链表中倒数第K个位置上的节点,K为正整数。若查找成功,输出该节点的data值,并且返回1,否则,只返回0.
#include<stdio.h>
#include
#include
#include<stdlib.h>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
} LNode;
int findNode(LNode *head,int k)
{
LNode *q,*finds;
q=head->next;
finds=head;
int i=1;
while(q!=NULL)
{
q=q->next;
++i;
if(i>k)
{
finds=finds->next;
}
}
if(finds == head)//如果链表没有k个节点,直接返回
return 0;
else
{
cout<data;
return 1;
}
}
//关键部分结束
void saveListnext(LNode *&L,int x[],int n)//尾插
{
L = (LNode *)malloc (sizeof(LNode));
L->next=NULL;
LNode *q;
q=L;
LNode *s;
for(int i=0;i<n;i++)
{
s=(LNode *)malloc(sizeof(LNode));
s->data = x[i];
q->next=s;
q=q->next;
}
q->next=NULL;
}
void printList(LNode *L)
{
LNode *q;
q=L->next;
int i=0;
while(q!=NULL)
{
if(i++)
putchar(’ ');
printf("%d",q->data);
q=q->next;
}
printf("\n");
}
int main(void)
{
LNode *L;
int x[8]={4,5,6,7,8,9,10,11};
saveListnext(L,x,8);
printList(L);
findNode(L,4);
return 0;
}
9.设计一个算法,在递增链表中删除值域重复的节点。
输入 1 1 2 2 3 4 5 6 8 8
输出 1 2 3 4 5 6 8
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct LNode
{
int data;
struct LNode *next;
}LNode;
void printLNode (LNode *L)
{
LNode *q;
q=L;
q=q->next;
int i=0;
while(q!=NULL)
{
if(i++)
{
putchar(’ ');
}
printf("%d",q->data);
q=q->next;
}
printf("\n");
}
void saveLNodehead(LNode *&L,int x[])//尾插
{
L=(LNode *)malloc(sizeof(LNode));
L->next=NULL;
LNode *s,*q;
q=L;//指向头指针
for(int i=0;i<=9;i++)
{
if(x[i]==x[i+1])
continue;
s=(LNode *)malloc (sizeof(LNode));
s->data = x[i];
q->next=s;
q=q->next;
}
q->next=NULL;
}
int main (void)
{
LNode *L;
int x[11]={1,1,2,2,3,4,5,6,8,8,0};
saveLNodehead(L,x);
printLNode(L);
return 0;
}