实验一
一、实验题目:
单链表的实现
二、实验目的:
⑴ 掌握线性表的链接存储结构;
⑵ 验证单链表及其基本操作的实现;
⑶ 进一步理解算法与程序的关系,能够将单链表算法转换为程序。
三、实验内容:
⑴ 用头插法(或尾插法)建立带头结点的单链表;
⑵ 对已建立的单链表实现插入、删除、查找等基本操作。
实验提示:
定义单链表的数据类型——单链表结构体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;
}