链表的基本操作
原代码的调试
这里我们要注意在DEVC++中直接复制粘贴代码,运行的时候会出现一大堆错误,经过检查可以发现这是因为有部分代码被放在了/* */的注释中,所以我们需要将它放出来,并且记得在调用函数的时候就声明变量的类型。而且DEVC++中本身对NULL就有定义,所以最上边的定义NULL语句可以删去。DEVC++中是对delete有定义的,所以我们在定义删除函数那里需要将其名称改一下,这里我为了方便起见直接改成了deleter。下面的void main()可以改为int main() {return 0}的形式,我为了方便直接删除了void没加return 0也是可运行的。调试后的代码和运行效果如下
#include “stdio.h”
#include “malloc.h” /包含动态分配内存函数/
#define TRUE 1
#define FALSE 0
typedef int elemtype;
typedef struct node { /链表结点类型定义/
elemtype data; /结点数据域/
struct node *next; /结点的指针域/
} linklist;
linklist *creatlist() { /创建链表函数-以按下任意建开始创建,以输入字符’?'表示结束标志/
char ch;
int x;
linklist *head,r,p;
p=(linklist)malloc(sizeof(linklist));
head=p;
p->next=NULL;
r=p;
ch=getchar();
while(ch!=’?’) {
scanf("%d",&x);
p=(linklist)malloc(sizeof(linklist));
p->data=x;
p->next=NULL;
r->next=p;
r=r->next;
ch=getchar();
}
return (head);
}
int locate(linklist *head,elemtype k) { /定位检索函数-如链表中存在值为k的结点,则返回真,否则返回假/
linklist *s;
s=head->next;
while(s!=NULL)
if(s->data!=k)
s=s->next;
else
return TRUE;
return FALSE;
}
void insert(linklist *head,int i,elemtype x) { /在链表head的第i个位置插入 元素x/
linklist *s,*p;
int j;
p=head;
j=0;
while(p->next&&j<i-1) {
p=p->next;
j++;
}
if(!p||j>i-1) printf(“error!”);
s=(linklist *)malloc(sizeof(linklist));
if(!s) printf(“overflow!”);
s->data=x;
s->next=p->next;
p->next=s;
}
void deleter(linklist *head,int i) { /删除链表的第i个结点/
int j=0;
linklist *p,*s,*q;
p=head;
j=0;
while((p->next!=NULL)&&(j<i-1)) {
p=p->next;
j++;
}
if(p->next!=NULL) {
q=p->next;
p->next=p->next->next;
free(q);
} else printf(“illegal delete position,delete failed!”);
}
void print(linklist *head) { /打印出链表head中各个结点的值/
linklist *p;
p=head->next;
while(p!=NULL) {
printf("%d “,p->data);
p=p->next;
}
printf(”\n");
}
main() { /主函数/
linklist *head; /定义指向链表的指针head/
int x;
int i,j;
printf(“please input the initial node and start by any key(’?'execpt)end with ‘?’\n”);
head=creatlist();
printf(“we have created a linklist as follow:\n”);
print(head);
printf(“now start search,please input the search value:”);
scanf("%d",&x);
printf("\n");
if(locate(head,x)) printf(“exsist!\n”);
else
printf(“not exsist!\n”);
printf(“start insert operation,please input insert position:”);
scanf("%d",&i);
insert(head,i,x);
printf(“after insertion:\n”);
print(head);
printf(“now start delete operation,input the delete position please:”);
scanf("%d",&j);
deleter(head,j);
printf(“after deletion:\n”);
print(head);
}
输入的时候记得用英文?来结束
(1) 定义一个逆置函数diverse(L),把链表进行逆置。在主程序中调用该函数,分析操作结果。
不懂的同学可以从上图来分析出做法,本人字可能不太好认,可以私信问我
为了方便阅读,我删除了原来不需要的函数,源代码和运行效果如下:
#include “stdio.h”
#include “malloc.h” /包含动态分配内存函数/
#define TRUE 1
#define FALSE 0
typedef int elemtype;
typedef struct node { /链表结点类型定义/
elemtype data; /结点数据域/
struct node *next; /结点的指针域/
} linklist;
linklist *creatlist() { /创建链表函数-以按下任意建开始创建,以输入字符’?'表示结束标志/
char ch;
int x;
linklist *head,r,p;
p=(linklist)malloc(sizeof(linklist));
head=p;
p->next=NULL;
r=p;
ch=getchar();
while(ch!=’?’) {
scanf("%d",&x);
p=(linklist)malloc(sizeof(linklist));
p->data=x;
p->next=NULL;
r->next=p;
r=r->next;
ch=getchar();
}
return (head);
}
linklist *inverse (linklist *head) {
linklist *r,*p;
p=head->next;
head->next=NULL;
while(p!=NULL) {
r=p;
p=p->next;
r->next=head->next;
head->next=r;
}
}
void print(linklist *head) { /打印出链表head中各个结点的值/
linklist *p;
p=head->next;
while(p!=NULL) {
printf("%d “,p->data);
p=p->next;
}
printf(”\n");
}
main() { /主函数/
linklist *head; /定义指向链表的指针head/
int x;
int i,j;
printf(“please input the initial node and start by any key(’?'execpt)end with ‘?’\n”);
head=creatlist();
printf(“we have created a linklist as follow:\n”);
print(head);
printf(“逆置后的单链表如下\n”);
inverse(head);
print(head);
}
这里有个小小的bug,输入链表的时候需要先在前面打个空格,不然会导致吞数字。
(2) 定义一个函数delsame(L),把链表中重复的元素删除掉,只保留一个。在主程序中调用该函数,分析操作结果
在这个题中,我们先分析需要几个指针:
需要一个指针s指向头指针后面,还需要一个指针p指向s指针后面来遍历整个链表,判断是否有相同元素;若有相同元素,则删除这个节点,若没有则继续遍历;在这次循环遍历完成之后,s指针再指向下一个地方,重复上述步骤,所以我们需要3个指针,设其为p,q,s,这时画个图分析一下即可写出。
源代码和运行效果如下:
#include “stdio.h”
#include “malloc.h” /包含动态分配内存函数/
#define TRUE 1
#define FALSE 0
typedef int elemtype;
typedef struct node { /链表结点类型定义/
elemtype data; /结点数据域/
struct node *next; /结点的指针域/
} linklist;
linklist *creatlist() { /创建链表函数-以按下任意建开始创建,以输入字符’?'表示结束标志/
char ch;
int x;
linklist *head,r,p;
p=(linklist)malloc(sizeof(linklist));
head=p;
p->next=NULL;
r=p;
ch=getchar();
while(ch!=’?’) {
scanf("%d",&x);
p=(linklist)malloc(sizeof(linklist));
p->data=x;
p->next=NULL;
r->next=p;
r=r->next;
ch=getchar();
}
return (head);
}
void delsame(linklist *head) {
linklist *s,*p,*q;
s=head->next;
p=s->next;
q=s;
while(s!=NULL) {
p=s->next;
q=s;
while(p!=NULL) {
if(s->data==p->data) {
q->next=p->next;//q指向p处
free§;//释放p节点
p=(linklist *)malloc(sizeof(linklist));//重新生成p指针
p=q->next;//p指向此时q的下一个
} else {
q=p;
p=p->next;
}
}
s=s->next;//p完成一次遍历
}
}
void print(linklist *head) { /打印出链表head中各个结点的值/
linklist *p;
p=head->next;
while(p!=NULL) {
printf("%d “,p->data);
p=p->next;
}
printf(”\n");
}
main() { /主函数/
linklist *head; /定义指向链表的指针head/
int x;
int i,j;
printf(“please input the initial node and start by any key(’?'execpt)end with ‘?’\n”);
head=creatlist();
printf(“we have created a linklist as follow:\n”);
print(head);
printf(“删除相同元素后的单链表如下\n”);
delsame(head);
print(head);
}
以上就是数据结构实验报告二**