实验二 链表的基本操作

ZZU的学弟学妹们不要抄作业哦~(`Д´)

一、实验目的
1.掌握线性表的链式存储结构的表示和实现方法。
2.掌握链表基本操作的算法实现。

二、实验内容
1.建立单链表,并在单链表上实现插入、删除和查找操作(验证性内容)。
2.计算已知一个单链表中数据域值为一个指定值x的结点个数(应用性设计内容)。
3.建立双向循环链表,并在双向循环链表上实现插入、删除和查找操作(选做内容)。

三、实验要求
1.建立单链表,并在单链表上实现插入、删除和查找操作。
编程实现如下功能:
(1)根据输入的一系列整数,以0标志结束,用头插法建立单链表,并输出单链表中各元素值,观察输入的内容与输出的内容是否一致。
(2)在单链表的第i个元素之前插入一个值为x的元素,并输出插入后的单链表中各元素值。
(3)删除单链表中第i个元素,并输出删除后的单链表中各元素值。
(4)在单链表中查找第i个元素,如果查找成功,则显示该元素的值,否则显示该元素不存在。
2.计算已知一个单链表中数据域值为一个指定值x的结点个数。
⑴ 从键盘输入若干个整数,以此序列为顺序建立一个不带头结点的单链表;
⑵ 输出此单链表中的各个数据元素值;
⑶ 给定一个x的具体整数值,计算并返回此单链表中数据域值为x的结点个数值。
3.建立双向循环链表,并在双向循环链表上实现插入、删除和查找操作。
(1)输入链表的长度和各元素的值,用尾插法建立双向循环链表,并输出链表中各元素值,观察输入的内容与输出的内容是否一致。
(2)在双向循环链表的第i个元素之前插入一个值为x的元素,并输出插入后的链表中各元素值。
(3)删除双向循环链表中第i个元素,并输出删除后的链表中各元素值。
(4)在双向循环链表中查找值为x元素,如果查找成功,则显示该元素在链表中的位置,否则显示该元素不存在。

四、详细程序清单

//1.单链表 
#include   
#include   
  
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;

LinkList head,k;

void Show(LinkList t)//显示 
{ 	
	printf("当前链表元素为:");
	t=t->next; 
    while(t!=NULL)  
    {  
        printf("%d ",t->data);  
        t=t->next;  
    } 
    printf("\n");  
}  
  
void CreateHead(LinkList &L)//头插法创建单链表 
{
	head=(LinkList)malloc(sizeof(LNode));  
	head->next=NULL;
	head->data=NULL;
	LinkList p,t;
	int x;
	t=head;
	printf("请输入数值,以0结束\n");
    while(~scanf("%d",&x),x)
    { 
        p=(LinkList)malloc(sizeof(LNode));  
        p->data=x;  
		p->next=t->next; 
		t->next=p; 		
    }
} 
 
void CreateTail(LinkList &L)//尾插法创建单链表并显示 
{
	k=(LinkList)malloc(sizeof(LNode));  
	k->next=NULL;
	k->data=NULL;
	LinkList last,t,s;
	int x;
	last=k;
	s=k;
	printf("请输入数值,以0结束\n");
    while(~scanf("%d",&x),x)
    {
    	t=(LinkList)malloc(sizeof(LNode));
    	t->data=x;
    	t->next=NULL;
    	if(head==NULL){head=t;last=t;}
    	else{last->next=t;last=t;}		
	} 
}
int Insert(LinkList &L,int i,int e)//插入 
{
	LinkList t,p;
	int j=1;
	t=head;
	if(i<1){printf("插入错误\n");return 0;}
	if(i==1) //插入位置在表头 
    {
    	p=(LinkList)malloc(sizeof(LNode)); 
		p->data=e;
		p->next=t->next;
		head->next=p;
		printf("插入成功\n");
		return 0;	
    }   
	while(j<i-1&&L)
	{
			t=t->next;
			j++;
			if(t==NULL)
			{
				printf("插入错误\n");
				return 0;
			}
	}
	//插在非表头 
	t=t->next;
	p=(LinkList)malloc(sizeof(LNode)); 
	p->data=e;
	p->next=t->next;
	t->next=p;
	printf("插入成功\n");
}

int Delete(LinkList &L,int i)//删除 
{
	LinkList p,t;
	int j=0;
	p=head;
	if(i<1){printf("删除失败\n");return 0;}
	while(j<i-1&&L)
	{
			p=p->next;
			j++;
			if(p==NULL)
			{
				printf("删除失败\n");
				return 0;
			}	
	}	
	t=p->next;
	p->next=t->next;
	printf("删除成功\n");
	free(t);	
}

int Secrch(LinkList &L,int i)//查找 
{
	LinkList p;
	int j=0,e;
	p=head;
	if(i<1){printf("查找失败,该元素不存在\n");return 0;}
	while(j<i&&L)
	{
			p=p->next;
			j++;
			if(p==NULL)
			{
				printf("查找失败,该元素不存在\n");
				return 0;
			}	
	}
	e=p->data;
	printf("查找成功,第%d个元素为%d\n",i,e);	
}

void Calculate(LinkList &L,int i)
{
	LinkList p;
	p=k;
	int count=0;
	while(p->next!=NULL)
	{
		if(i==p->data) count++;	
		p=p->next;
	}
	printf("元素%d有%d个\n",i,count);	
}

int main()  
{  
	LinkList L;
    int select,i,e; 
    while(1)  
    {   
        printf("1.头插法建表 \t2.尾插法建表 \t3.插入 \t4.删除 \t5.查找 \t6.统计\n");   
        scanf("%d",&select);  
        switch(select)  
        {    
        case 1:  
            CreateHead(L);
			Show(head);  
            break;  
        case 2: 
			CreateTail(L);
			Show(k);
            break;    
		case 3:	
			printf("输入位置和要插入的元素\n");
			scanf("%d%d",&i,&e);
			Insert(L,i,e);
			Show(head);
			break; 
		case 4: 
			printf("输入要删除的元素的位置\n");
			scanf("%d",&i);
            Delete(L,i);
            Show(head);
            break;
        case 5: 
			 printf("输入要查找的元素的位置\n");
			 scanf("%d",&i);
			 Secrch(L,i);
             break;
        case 6: 
			printf("输入要统计的元素值\n");
			scanf("%d",&i);
			Calculate(L,i);
			break;
		case 7:  
			return 0;  
        default: 
		    printf("输入错误\n");
            break; 
        }  
    }  
    return 0;  
}  

//2.双向循环链表 DC:Double Circular
#include   
#include  
 
typedef struct DCLNode{
int data;
struct DCLNode *prior;
struct DCLNode *next;
}DCLNode,*DCLinkList;

DCLinkList w;//尾 

void Create(DCLinkList &L,int n)
{
	DCLinkList p,t;
	int x;
	t=L;
	scanf("%d",&x);
	while(1)
	{
		n--;
		if(!n){t=p;break;} 
		p=(DCLinkList)malloc(sizeof(DCLNode));
		t->data=x;
		t->next=p;
		p->prior=t;
		scanf("%d",&x);
		p->data=x;
		t=p;
	}
	L->prior=t;
	t->next=L;
	w=t;
}
void Show(DCLinkList L)
{
	DCLinkList p;
	printf("当前链表元素为:");
	for(p=L;p->next!=L;p=p->next)
	{
		printf("%d ",p->data);
	}
	printf("%d ",p->data);
	printf("\n");	
}
int Insert(DCLinkList &L,int i,int e)//插入 
{
	DCLinkList t,p;
	int j=1;
	t=w;
	if(i<1){printf("插入错误\n");return 0;}  
	while(j<=i-1)
	{
			t=t->next;
			j++;
	}
	p=(DCLinkList)malloc(sizeof(DCLNode)); 
	p->data=e;
	p->next=t->next;
	t->next=p;
	p->prior=t;
	printf("插入成功\n");
}
int Delete(DCLinkList &L,int i)//删除 
{
	DCLinkList p,t;
	int j=0;
	p=w;
	if(i<1){printf("删除失败\n");return 0;}
	while(j<i-1)
	{
			p=p->next;
			j++;	
	}	
	t=p->next;
	p->next=t->next;
	t->next->prior=p;
	printf("删除成功\n");
	free(t);	
}

int Secrch(DCLinkList &L,int e)//查找 
{
	DCLinkList p;
	int j=1;
	p=w->next;
	while(1)
	{
			if(p->data==e){printf("查找成功,%d元素的位置为%d\n",e,j);return 0;}
			if(p==w){printf("查找失败,该元素不存在\n");return 0;}
			p=p->next;
			j++;
	}
}

int main()  
{  
	DCLinkList L;
    int select,i,e;
	L=(DCLinkList)malloc(sizeof(DCLNode)); 
    L->data=NULL;
    L->next=L;
    L->prior=L;
    while(1)  
    {   
        printf("1.建表 \t2.插入 \t3.删除 \t4.查找\n");   
        scanf("%d",&select);  
        switch(select)  
        {    
        case 1: 
			printf("输入链表长度\n");
			scanf("%d",&i);
			printf("输入各元素的值\n");
            Create(L,i);
			Show(w->next);  
            break;    
		case 2:	
			printf("输入位置和要插入的元素\n");
			scanf("%d%d",&i,&e);
			Insert(L,i,e);
			Show(w->next);
			break; 
		case 3: 
			printf("输入要删除的元素的位置\n");
			scanf("%d",&i);
            Delete(L,i);
            Show(w->next);
            break;
        case 4: 
			 printf("输入要查找的元素\n");
			 scanf("%d",&i);
			 Secrch(L,i);
             break;
		case 5:  
			return 0;  
        default: 
		    printf("输入错误\n");
            break; 
        }  
    }  
    return 0;  
}  

五、程序运行结果
1.单链表:
实验二 链表的基本操作_第1张图片

2.双向循环链表:
实验二 链表的基本操作_第2张图片

六、实验心得体会
1.进行除Create操作外的操作时,单链表的head最好不要变;
2.上课的时候没有理解为什么head指针的data要为NULL,经过实际操作后发现了头指针为空时,便于遍历、插入、查找等操作;
3.双向循环链表中的节点都不为空,在遍历等操作的时候和单链表有所不同,可以从尾指针->next开始;
5.错误很多,调试很烦,要有耐心。

你可能感兴趣的:(数据结构实验_C语言)