您的位置:首页 > 理论基础 > 数据结构算法

有关算法与数据结构的考题解答参考汇总 [C++] [链表] · 第二篇

2021-09-29 17:40 891 查看

早先年考研的主考科目正是【算法与数据结构】,复习得还算可以。也在当时[百度知道]上回答了许多相关问题,现把他们一起汇总整理一下,供读者参考。

 

【1】

原题目地址:https://zhidao.baidu.com/question/1495131980697139059.html?entry=qb_uhome_tag

题目: 建立一个有5个结点的单向链表,每个结点包含姓名,年龄和工资.编写下列函数,然后在main函数中测试. 2、建立一个有5个结点的单向链表,每个结点包含姓名、年龄和工资。编写下列函数,然后在main函数中测试。 (1)用于建立链表的函数; (2)用来输出链表的函数; (3)编写插入结点的函数,在指定位置插入一个新结点; (4)编写删除结点的函数,在指定位置删除一个结点。 要用C语言TT

答:

#include<stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <windows.h>

typedef struct Node
{
char name[6];
int age;
int wage;
struct Node *next;
}NODE,*PNODE;

PNODE Init();
void Show(PNODE);
PNODE Insert(PNODE,int);
PNODE Delete(PNODE,int);

PNODE Init()
{
PNODE head = NULL;
PNODE pTail = NULL;
int t=0;
for(int i=0; i<5; i++)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(!pNew)
exit(-1);
printf("---%d---\n",i+1);
printf("输入姓名:");
scanf("%s",&pNew->name);
printf("输入年龄:");
scanf("%d",&pNew->age);
printf("输入工资:");
scanf("%d",&pNew->wage);
if(0==t)
{
head = (PNODE)malloc(sizeof(NODE));
if(!head)
exit(-1);
head = pNew;
pNew->next = NULL;
pTail = head;
t=1;
}
else
{
pTail->next = pNew;
pNew->next= NULL;
pTail = pNew;
}
}
return head;
}

void Show(PNODE head)
{
int i=1;
PNODE p =  head;
while(NULL!= p)
{

printf("---%d---\n",i);
printf("NAME:%s\n",p->name);
printf("AGE:%d\n",p->age);
printf("WAGE:%d\n",p->wage);
p = p->next;
i++;
}
return;
}

PNODE Insert(PNODE head,int pos)
{
PNODE p = head;
PNODE p2 = head;
PNODE p1 = p;
int t = pos;
pos-=1;
while(pos!=0)
{
p1 = p;
p = p->next;
pos--;
}
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(!pNew)
exit(-1);
printf("---%d---\n",t);
printf("输入姓名:");
scanf("%s",&pNew->name);
printf("输入年龄:");
scanf("%d",&pNew->age);
printf("输入工资:");
scanf("%d",&pNew->wage);
p1->next = pNew;
pNew->next = p;

return p2;
}

PNODE Delete(PNODE head,int pos)
{
PNODE p = head;
PNODE p2 = head;
PNODE p1 = p;
pos-=1;
while(pos!=0)
{
p1 = p;
p = p->next;
pos--;
}
p1->next = p->next;
free(p);
p = NULL;

return p2;
}

int main()
{
PNODE head = NULL;
head = Init();
Show(head);
head = Insert(head,2);
Show(head);
head = Delete(head,4);
Show(head);
system("pause");
return 0;
}

【PS】我用的是无头指针的单链表。有些地方还可以改进,健壮程序。

 

【2】

原题目地址:https://zhidao.baidu.com/question/2074848498587475988.html?entry=qb_uhome_tag

题目: 编写程序,创建成一个正序排列的单链线性表,可实现删除一个元素,保持链表的正序。 在执行完每个操作后将其输出。输入的无序序列为:(60,55,40,70,10,80)

答:

#include<stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <windows.h>

typedef struct Node
{
int data;
struct Node *next;
}NODE,*PNODE;

PNODE Init();
void Show(PNODE);
PNODE Delete(PNODE);
PNODE Sort(PNODE);

PNODE Init()
{
PNODE head = NULL;
PNODE pTail = NULL;
int t=0;
for(int i=0; i<6; i++)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(!pNew)
exit(-1);
printf("[%d]",i+1);
scanf("%d",&pNew->data);
if(0==t)
{
head = (PNODE)malloc(sizeof(NODE));
if(!head)
exit(-1);
head = pNew;
pNew->next = NULL;
pTail = head;
t=1;
}
else
{
pTail->next = pNew;
pNew->next= NULL;
pTail = pNew;
}
}
return head;
}

void Show(PNODE head)
{
int i=1;
PNODE p =  head;
while(NULL!= p)
{

printf("[%d]:%d\n",i,p->data);
p = p->next;
i++;
}
putchar(10);
return;
}

PNODE Delete(PNODE head)
{
int pos;
PNODE p = head;
PNODE p2 = head;
PNODE p1 = p;

printf("想删除的节点:");
scanf("%d",&pos);
pos-=1;
while(pos!=0)
{
p1 = p;
p = p->next;
pos--;
}
p1->next = p->next;
free(p);
p = NULL;

return p2;
}

PNODE Sort(PNODE head)
{
PNODE p1 = head;
PNODE p2 = NULL;
PNODE p3 = head;
int i,j,t;
int len = 0;
while(p1 != NULL)
{
p1 = p1->next;
len++;
}
p1 = p3;
p2 = p1->next;
for(i = 0; i < len-1; i++,p1 = p1->next)
{
for(j = i+1,p2 = p1->next; j < len; j++,p2 = p2->next)
{
if(p1->data > p2->data)
{
t = p1->data;
p1->data = p2->data;
p2->data = t;
}
}
}
return p3;
}

int main()
{
PNODE head = NULL;
head = Init();
printf("输入的数为:\n");
Show(head);
printf("-------------------\n");
printf("排序之后的数为:\n");
head = Sort(head);
Show(head);
printf("删除之后的数为:\n");
head = Delete(head);
Show(head);
printf("-------------------\n");
system("pause");
return 0;
}

上机测试: 【PS】这个是无头指针的做法!有些地方还能改进。

 

【3】

原题目地址:https://zhidao.baidu.com/question/919580753653115019.html?entry=qb_uhome_tag

题目: 关于链表的,对于我的代码,1,如果我原来只有一个结点,我删除这唯一的一个,2我原本就没有输入结点,或者输入了几个结点,要删除的确是一个不存在的结点,就会出现如图的情况,下面有我的代码

#include<stdio.h>
#include<stdlib.h>
#define S sizeof(struct Student)

struct Student {
int num;
char name[20];
double math;
struct Student *next;
};

void main()
{
struct Student *head, *p1, *p2, *p;
int n=0, k;
p1=(struct Student *)malloc(S);
scanf("%d%s%lf", &p1->num, p1->name, &p1->math);
head=NULL;
while (p1->num!=0) {
n++;
if (n==1) head=p1;
else p2->next=p1;
p2=p1;
p1=(struct Student *)malloc(S);
scanf("%d%s%lf", &p1->num, p1->name, &p1->math);
}
p2->next=NULL;
printf("删除前:\n学号\t名字\t数学成绩\n");
p=head;
if (head!=NULL)
do {
printf("%d\t%s\t%.2f\n", p->num, p->name, p->math);
p=p->next;
} while (p!=NULL);
printf("请输入要删除的学号:");
scanf("%d", &k);
while (head!=NULL&&head->num==k) {
p2=head;
head=head->next;
free(p2);
}
p1=head;
p2=head->next;
while (p2!=NULL) {
if (p2->num==k) {
p1->next=p2->next;
free(p2);
} else p1=p2;
p2=p1->next;
}
printf("删除后:\n学号\t名字\t数学成绩\n");
p=head;
if (head!=NULL)
do {
printf("%d\t%s\t%.2f\n", p->num, p->name, p->math);
p=p->next;
} while (p!=NULL);
}

答:

#include<stdio.h>
#include<stdlib.h>
#include <windows.h>

#define S sizeof(struct Student)
struct Student
{
int num;
char name[20];
double math;
struct Student *next;
};

struct Student * Init(void);
void Show(struct Student *);
struct Student * Delete(struct Student *);

struct Student * Init(void)
{
struct Student *head = NULL,*p1 = NULL,*p2 = NULL,*p = NULL;
int n = 0;
p1 = (struct Student *)malloc(S);
if(!p1)
exit(-1);
scanf("%d%s%lf",&p1->num,p1->name,&p1->math);
head = NULL;
while(p1->num != 0)
{
n++;
if(1 == n) head = p1;
else p2->next = p1;
p2 = p1;
p1 =(struct Student *)malloc(S);
if(!p1)
exit(-1);
scanf("%d%s%lf",&p1->num,p1->name,&p1->math);
}
p2->next = NULL;
return head;
}

void Show(struct Student * head)
{
struct Student * p = head;
printf("\n学号\t名字\t数学成绩\n");
if(head != NULL)
do{
printf("%d\t%s\t%.2f\n",p->num,p->name,p->math);
p = p->next;
}while(p != NULL);
return;
}

struct Student * Delete(struct Student *head)
{
int k,t = 0;
struct Student *p2,*p1,*p;
p = head;
p1 = head;
p2 = p1;
printf("请输入要删除的学号:");
scanf("%d",&k);

if(k == head->num)
{
p2 = p1 = p = head->next;
free(head);
head = NULL;
t = 1;
}
while(p1 != NULL)
{
if(p1->num == k)
{
p2->next = p1->next;
free(p1);
p1 = p2->next;
t = 1;
}
else
{
p2 = p1;
p1 = p1->next;
}
}
if(0 == t)
printf("\n根据您输入的没找到相应节点!\n");
return p;
}

int main()
{
struct Student * head = NULL;
head = Init();
printf("删除前:");
Show(head);
head = Delete(head);
printf("删除后:");
Show(head);

system("pause");
return 0;
}

【PS】我不太明白您的意思。上面是我根据您给的程序修改过的。您先试试。有问题提出。另有一些值得提出的:

1.建议您学习规范的编程书写。每个功能写相应的函数,不要都写在main函数里面,C语言是面向过程语言,这样写,思路清晰,维护也方便!

2.每次动态分配内存之后要添加一句 if 语句,提高程序健壮性。

3.每次建立了指向结构体的指针,要初始化一个值(一个地址,没有指定就NULL),避免野指针!也包括删掉了一个指向节点的指针后,这个指针也要清零!

4.特别是Delete函数里面,我感觉您的程序里漏了几句重要语句!

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: