【数据结构实验一】- 单链表的实现,附-集合A、B的交并差集

实验一


一、实验题目:

单链表的实现

二、实验目的:

⑴ 掌握线性表的链接存储结构;
⑵ 验证单链表及其基本操作的实现;
⑶ 进一步理解算法与程序的关系,能够将单链表算法转换为程序。

三、实验内容:

⑴ 用头插法(或尾插法)建立带头结点的单链表;
⑵ 对已建立的单链表实现插入、删除、查找等基本操作。

实验提示:

定义单链表的数据类型——单链表结构体Node在Node基础上实现题目要求的插入、删除、查找等基本操作,为便于查看操作结果,设计一个输出函数依次输出顺序表的元素。简单起见,本实验假定线性表的数据元素为int型,要求学生:
(1)将实验程序调试通过后,用模板类改写;
(2)加入求线性表的长度等基本操作;
(3)重新给定测试数据,验证抛出异常机制。

演示实验

程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

typedef int DataType;
typedef struct Node
{
	DataType data;
	struct Node *next;
}Node;

Node *InitList();
void PrintList(Node *first);
int Length(Node *first);
int Locate(Node *first, DataType x);
int Insert(Node *first, int i, DataType x);
Node *CreatList(DataType a[], int n);
int Delete(Node *first, int i, DataType *ptr);
void DestroyList(Node *first);

int main( )
{
	int r[5] = {1, 2, 3, 4, 5}, i, x;
	Node *first = NULL;
	first = CreatList(r, 5);
	
	printf("当前线性表的数据为:");
	PrintList(first);                       
	Insert(first, 2, 8);                    
	printf("执行插入操作后数据为:"); 
	PrintList(first);                     
	printf("当前单链表的长度为:%d\n", Length(first));     
	printf("请输入查找的元素值:");
	scanf("%d", &x);
	i = Locate(first, x);
	if (i != 0) 
		printf("元素%d的元素位置为:%d\n", x, i);   
	else 
		printf("单链表中没有元素%d\n", x);
	printf("请输入要删除第几个元素:");
	scanf("%d", &i);
	if (Delete(first, i, &x) == 1)
	{                       
		printf("删除的元素值是%d,\n执行删除操作后数据为:", x);
    	PrintList(first);                               
  	}
	else 
		printf("删除操作失败\n");
	DestroyList(first);
  	return 0;
}

Node *InitList( )
{
	Node *first = (Node *)malloc(sizeof(Node));
	first->next = NULL;
	return first;
}

void PrintList(Node *first)
{
	Node *p = first->next;
	while (p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

int Length(Node *first)
{
	Node *p = first->next;
	int count = 0;
	while (p !=NULL)
	{
		p = p->next;
		count++;
	}
	return count; 
}

int Locate(Node *first, DataType x) 
{
	Node *p = first->next;
	int count = 1;                     
	while (p != NULL)
	{
		if (p->data == x) return count;
		p = p->next;                   
		count++;
	}
  	return 0;
}

int Insert(Node *first, int i, DataType x)
{
	Node *s = NULL, *p = first ;
	int count = 0;
	while (p != NULL && count < i - 1)
	{
    	p = p->next;
		count++;
	}
	if (p == NULL)
	{
		printf("位置错误,插入失败\n"); 
		return 0;
	}
  	else
	{ 
		s = (Node *)malloc(sizeof(Node)); 
		s->data = x;
    	s->next = p->next; p->next = s;
    	return 1;
	}
}

Node *CreatList(DataType a[ ], int n)
{
	int i;
	Node *s = NULL;
	Node *first = (Node *)malloc(sizeof(Node));
	first->next = NULL;
	for (i = 0; i < n; i++)
	{ 
 		s = (Node *)malloc(sizeof(Node));
		s->data = a[i];
		s->next = first->next; first->next = s;
	}
	return first;
}

int Delete(Node *first, int i, DataType *ptr)
{
	Node *p = first, *q = NULL;
	int count = 0;
	DataType x;
	while (p != NULL && count < i - 1)
	{
    	p = p->next;
    	count++;
	}
	if (p == NULL || p->next == NULL)
	{
		printf("位置错误,删除失败\n ");
		return 0;
	}
	else
	{
	q = p->next; *ptr = q->data;
	p->next = q->next;
	free(q);
	return 1;
	}
}

void DestroyList(Node *first)
{
	Node *p = first;
	while (first != NULL)
	{
		first = first->next;
		free(p);
		p = first;
	}
}
程序运行结果截图:

在这里插入图片描述

四、实验心得体会

通过本次实验我学会了建立单链表和执行相关操作

⑴ 用头插法(或尾插法)建立带头结点的单链表;
⑵ 对已建立的单链表实现插入、删除、查找等基本操作。

希望我能在以后的实验中更加熟练的运用。


附:集合A、B的交并差集

代码:
/*集合A、B的交并差集*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef int DataType;
typedef struct Node
{
	DataType data;
	struct Node *next;
}Node; 

void InitList(Node *&L)
{
    L = (Node *)malloc(sizeof(Node));
    L->next=NULL;
}
/* 向单链表中插入数据元素 */
int ListInsert(Node *&L,int x,int e)
{
    int j = 0;
    Node *p = L, *s;
    while(p!=NULL && j<x-1)
    {
        p = p->next; j++;
    }
    if(p==NULL)
        return 0;
    else
    {
        s = (Node *)malloc(sizeof(Node));
        s->data = e;
        s->next = p->next;
        p->next = s;
        return 1;
    }
}
/* 输出单链表 */
void DispList(Node *L)
{
    Node *p = L->next;
    while(p!=NULL)
    {
        printf("%d ",p->data); p = p->next;
    }
    printf("\n");
}
/* 在单链表中查找元素 */
int LocateElem(Node *L,DataType e)
{
    Node *p = L; int i = 0;
    while(p!=NULL && p->data!=e)
    {
        p = p->next; i++;
    }
    if(p==NULL)
        return 0;
    else
        return i;
}
/* 删除单链表中第 i 个元素*/
int ListDelete(Node *&L,int i,DataType &e)
{
    int j = 0;
    Node *p = L, *q;
    while(p!=NULL && j < i - 1)
    {
        p = p->next; j++;
    }
    if(p==NULL)
        return 0;
    else
    {
        q = p->next;
        if(q==NULL)
            return 0;
        e = q->data;
        p->next = q->next;
        free(q);
        return 1;
    }
}
/* 删除单链表 */
void DestroyList(Node *&L)
{
    Node *p = L;
    Node *q = p->next;
    while(q!=NULL)
    {
        free(p);
        p = q;
        q = p->next;
    }
    free(p);
}

void CreateListR(Node *&L,DataType e[],int n)
{
    InitList(L); int i;
    for(i = 0;i < n; ++i)
    {
        if(!LocateElem(L,e[i]))
            ListInsert(L,i+1,e[i]);
    }
}

void InsterSect(Node *a,Node *b,Node *&c)
{
    DestroyList(c);
    InitList(c);
    Node *p = a->next;
    int i = 0;
    while(p!=NULL)
    {
        if(LocateElem(b,p->data))
            ListInsert(c,++i,p->data);
        p = p->next;
    }
}

void Subs(Node *a,Node *b,Node *&c)
{
    DestroyList(c);
    InitList(c);
    Node *p = a->next;
    int i = 0;
    while(p!=NULL)
    {
        if(!LocateElem(b,p->data))
            ListInsert(c,++i,p->data);
        p = p->next;
    }
}

void Union(Node *a,Node *b,Node *&c)
{
    InitList(c);
    Node *p = a->next;
    Node *q = b->next;
    int k = 0;
    while(p!=NULL && q!=NULL)
    {
        if(p->data < q->data)
        {
            ListInsert(c,k+1,p->data);
            p = p->next; k++;
        }
        else if(p->data == q->data)
        {
            ListInsert(c,k+1,p->data);
            p = p->next;
            q = q->next;
            k++;
        }
        else
        {
            ListInsert(c,k+1,q->data);
            q = q->next; k++;
        }
    }
    while(p!=NULL)
    {
        ListInsert(c,k+1,p->data);
        p = p->next; k++;
    }
    while(q!=NULL)
    {
        ListInsert(c,k+1,q->data);
        q  = q->next; k++;
    }
}

void sort(Node *&L)
{
    Node *p , *pre, *q, *k;
    InitList(p);
    int i = 0, c;
    while(L->next != NULL) 
    {
        pre = L ->next;
        c = pre->data;
        while(pre!=NULL)
        {
            if(c>=pre->data)
                c = pre->data;
            pre = pre->next;
        }
        ListInsert(p,++i,c);
        int tag = LocateElem(L,c);
        ListDelete(L,tag,c);
    }
    L = p;
}

int main( )
{
    Node *ha, *hb, *hc;
    DataType a[]={3,5,7,2};
    DataType b[]={1,3,2,5,9,6};
    printf("集合的运算如下\n");
    CreateListR(ha,a,4);
    CreateListR(hb,b,6);
    printf("原集合A:"); DispList(ha);
    printf("原集合B:"); DispList(hb);
    sort(ha);							//排序 
    sort(hb);
    printf("有序集合A:"); DispList(ha);
    printf("有序集合B:"); DispList(hb);
    Union(ha,hb,hc);
    printf("A、B集合的并集:"); DispList(hc);
    InsterSect(ha,hb,hc);
    printf("A、B集合的交集:"); DispList(hc);
    Subs(ha,hb,hc);
    printf("A、B集合的差集:"); DispList(hc);
    DestroyList(ha);
    DestroyList(hb);
    DestroyList(hc);
    return 0;
}

运行结果

在这里插入图片描述

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值