实验名称 线性表及其应用
一、实验目的:
1.熟悉C语言的上机环境,进一步掌握C语言的结构特点。
2.掌握线性表的顺序存储结构的定义及C语言实现。
3.掌握线性表的链式存储结构——单链表的定义及C语言实现。
4.掌握线性表在顺序存储结构即顺序表中的各种基本操作。
5.掌握线性表在链式存储结构——单链表中的各种基本操作。
二、实验环境:
Visual C++
三、实验内容:
(写出主要的内容)
- 建立含n个数据元素的顺序表并输出该表中各元素的值及顺序表的长度。
#include<stdio.h>
typedef struct
{
int elem[100];
int last;
}SqeList;
int main()
{
SqeList L,*p;
printf("请输入顺序表的长度:");
scanf("%d",&L.last);
for(int i=0;i<=L.last;i++)
L.elem[i]=i;
p=&L;
for(i=1;i<=L.last;i++)
printf("%d ",p->elem[i-1]);
printf("\n顺序表的长度:%d\n",L.last);
return 0;
}
结果如下:
请输入顺序表的长度:10
0 1 2 3 4 5 6 7 8 9
顺序表的长度:10
- 利用前面的实验先建立一个顺序表L={21,23,14,5,56,17,31},然后在第i个位置插入元素68。
#include <stdio.h>
#define MAXSIZE 100
#define OVERFLOW -2
#define OK 1
#define ERROR 0
typedef int Status;
typedef int elemtype;
typedef struct
{
elemtype vec[MAXSIZE];
int length;
}sqList;
Status initList(sqList &L,int k)//线性表的初始化
{
int i;
L.length=k;//!
printf("input the List:\n");
for(i=0;i<k;i++)
{
scanf("%d",&L.vec[i]);
}
return OK;
}
int insert(sqList &L,int i,int x)//线性表的插入 //记得要加&
{
int j;
if(L.length>=MAXSIZE)
{ printf("the List is OVERFLOW.\n");
return ERROR;
}
else if((i<1)||(i>L.length+1))
{
printf("position is not correct.\n");
return ERROR;
}
else
{ printf("input the List:");
for(j=L.length-1;j>=i-1;j--)
{
L.vec[j+1]=L.vec[j];
}
L.vec[i]=x;
L.length++;
}
return OK;
}
int main()
{
int i,n,x;
sqList la;
printf("iuput the the length of List:");//输入表的长度
scanf("%d",&n);
initList(la,n);
printf("iuput the insert location:");
scanf("%d",&i);
printf("iuput the insert number:");
scanf("%d",&x);
if(insert(la,i,x))//输出插入后线性表的长度和数据
{
printf("the new List's length is:%d\n",la.length);
printf("the new List's data is:\n");
for(i=0;i<la.length;i++)
printf("%d ",la.vec[i]);
}
else
{
printf("can't insert the data!\n");
}
return 0;
}
输出结果:
iuput the the length of List:7
input the List:
21 23 14 5 56 17 31
iuput the insert location:3
iuput the insert number:68
input the List:the new List's length is:8
the new List's data is:
21 23 14 68 5 56 17 31
- 建立一个带头结点的单链表,结点的值域为整型数据。要求将用户输入的数据按尾插入法来建立相应单链表。
#include <stdio.h>
#include <stdlib.h>
typedef struct k
{
int data;
struct k* next;
}Node; /*创建链表*/
Node* initList()
{ /*初始化*/
Node *h=(Node *)malloc(sizeof(Node));
h->next=NULL;
return h;
}
Node* creatList()
{ /*尾插法创建*/
Node *h, *tail,*q;
int x;
h=(Node *)malloc(sizeof(Node));
h->next=NULL;
tail=h; /*tail类似于标签*/
printf("input nums, endby -1:\n");
scanf("%d",&x);
while(x!=-1){
//1、造结点q,并赋值;
q=(Node *)malloc(sizeof(Node));
q->data=x;
q->next=NULL;
//2、将q插入链表;
tail->next=q;
tail=q;
//3、继续读
scanf("%d",&x);
}
return h;
}
void printList(Node *h)
{ /*输出函数*/
if(h->next==NULL) return;
for(h=h->next;h!=NULL; h=h->next)
if(h->next!=NULL)
printf("%d->", h->data);
else
printf("%d",h->data);
}
int main()
{
Node *h;
h=creatList();
printf("\n链表为:\n");
printList(h);
}
输出结果为:
input nums, endby -1:
4 8 56 4 3 56 13 5 15 4 -1
链表为:
4->8->56->4->3->56->13->5->15->4
四、思考与提高
1. 如果按由表尾至表头的次序输入数据元素,应如何建立顺序表。
使用头插入法建立链表
2. 在main函数里如果去掉L=&a语句,会出现什么结果?
无法传递地址
五、完整参考程序
1.顺序线性表的建立、插入及删除。
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define ElemType int
#define MAXSIZE 100 /*此处的宏定义常量表示线性表可能达到的最大长度*/
typedef struct
{
ElemType elem[MAXSIZE]; /*线性表占用的数组空间*/
int last; /*记录线性表中最后一个元素在数组elem[ ]中的位置(下标值),空表置为-1*/
}SeqList;
void initial(SeqList *v) //初始化线性表
{//初始化线性表
int i;
printf("请输入初始线性表长度:n="); //输入线性表初始化时的长度
scanf("%d",&v->last);
printf("请输入从1到%d的各元素\n",v->last);
getchar();
for(i=0;i<v->last;i++) scanf("%d",&v->elem[i]); //输入线性表的各元素
v->last--;
}
int InsList(SeqList *L,int i,ElemType e) //在线性表中插入元素
{
//实验完成该部分的内容
int k;
for(k=L->last;k>i-1;k--)
L->elem[k+1]=L->elem[k];
L->elem[i-1]=e;
L->last++;
return OK;
}
int DelList(SeqList *L,int i,ElemType *e)
/*在顺序表L中删除第i个数据元素,并用指针参数e返回其值。i的合法取值为1≤i≤L.last+1 */
{
//实验完成该部分的内容
int k;
if((i<1)||(i>L->last))
{
printf("删除的位置不合法!");
return ERROR;
}
*e=L->elem[i-1];
for(k=i;k<L->last;k++)
L->elem[k-1]=L->elem[k];
L->last--;
return OK;
}
int Locate(SeqList L, ElemType e)
{
//实验完成该部分的内容
int i=0;
while((i<=L.last)&&L.elem[i]!=e)
i++;
if(i<=L.last)
return(i+1);
else
return(-1);
}
void print(SeqList S)
{
int i;
for(i=0;i<=S.last;i++)
printf("%5d",S.elem[i]);
printf("\n");
}
void main()
{SeqList S; //S为一线性表
int loc,flag=1;
char j;
int ch;
int temp;
printf("本程序用来实现顺序结构的线性表。\n");
printf("可以实现查找、插入、删除等操作。\n");
initial(&S); //初始化线性表
while(flag)
{ printf("请选择:\n");
printf("1.显示所有元素\n");
printf("2.插入一个元素\n");
printf("3.删除一个元素\n");
printf("4.查找一个元素\n");
printf("5.退出程序 \n");
scanf(" %c",&j);
switch(j)
{case '1':print(S); break; //显示所有元素
case '2':{printf("请输入要插入的元素和插入位置:\n");
printf("格式:数据,位置;例如:a,2\n");
scanf(" %d,%d",&ch,&loc); //输入要插入的元素和插入的位置
temp=InsList(&S,loc,ch); //插入
if(temp==ERROR) printf("插入失败!\n"); //插入失败
else {printf("插入成功!\n"); print(S);} //插入成功
break;
}
case '3':{printf("请输入要删除元素的位置:");
scanf("%d",&loc); //输入要删除的元素的位置
temp=DelList(&S,loc,&ch); //删除
if(temp==OK) printf("删除了一个元素:%d\n",ch); //删除成功
else printf("该元素不存在!\n"); //删除失败
print(S);
break;
}
case '4':{printf("请输入要查找的元素:");
scanf(" %d",&ch); //输入要查找的元素
loc=Locate(S,ch); //定位
if(loc!=-1) printf("该元素所在位置:%d\n",loc); //显示该元素位置
else printf("%c 不存在!\n",ch);//当前元素不存在
break;
}
default:flag=0;printf("程序结束,按任意键退出!\n");
}
}
getchar();
}
2.链式线性表的建立、插入及删除。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int ElemType;
typedef struct Node /*结点类型定义*/
{
ElemType data;
struct Node * next;
}Node, *LinkList; /* LinkList为结构指针类型*/
void init_linklist(LinkList *l)/*对单链表进行初始化*/
{
*l=(LinkList)malloc(sizeof(Node)); /*申请结点空间*/
(*l)->next=NULL; /*置为空表*/
}
void CreateFromTail(LinkList L)
{
//实验完成该部分的内容
Node *r, *s;
int c;
int flag =1; /*设置一个标志,初值为1,当输入-1时,flag为0,建表结束*/
r=L; /*r指针动态指向链表的当前表尾,以便于做尾插入,其初值指向头结点*/
printf("请输入数据,以-1结束:"); //输入生成单链表时的元素
while(flag) /*循环输入表中元素值,将建立新结点s插入表尾*/
{
scanf("%d",&c);
if(c!=-1)
{
s=(Node*)malloc(sizeof(Node));
s->data=c;
r->next=s;
r=s;
}
else
{
flag=0;
r->next=NULL; /*将最后一个结点的next链域置为空,表示链表的结束*/
}
}
}
int InsList(LinkList L,int i,ElemType e)
/*在带头结点的单链表L中第i个位置插入值为e的新结点*/
{
//实验完成该部分的内容}
int DelList(LinkList L,int i,ElemType *e)
/*在带头结点的单链表L中删除第i个元素,并将删除的元素保存到变量*e中*/
{
//实验完成该部分的内容
Node *pre,*s;
int k;
if(i<=0) return ERROR;
pre=L; k=0;
while(pre!=NULL&&k<i-1)
{
pre=pre->next;
k=k+1;
}
if(pre==NULL)
{
printf("插入位置不合理!");
return ERROR;
}
s=(Node *)malloc(sizeof(Node));
s->data=e;
s->next=pre->next;
pre->next=s;
return OK;
}
int Locate( LinkList L,ElemType key)
/*在带头结点的单链表L中查找其结点值等于key的结点,若找到则返回该结点的位置p,否则返回NULL*/
{
Node *p;
int n=0;
p=L->next; /*从表中第一个结点开始 */
while (p!=NULL)
{
n++;
if (p->data!=key)
p=p->next;
else
break; /*找到结点值=key时退出循环 */
}
if(p==NULL)n=0;
return n;
}
Node * Get (LinkList L, int i)
/*在带头结点的单链表L中查找第i个结点,若找到(1≤i≤n),则返回该结点的存储位置; 否则返回NULL*/
{
//实验完成该部分的内容
int j;
Node *p;
if(i<=0)return NULL;
p=L;j=0;
while((p->next!=NULL)&&(j<i))
{
p=p->next;
j++;
}
if(i==j) return p;
else return NULL;
}
void Print(LinkList v)
{//显示链表所有元素
LinkList q;
q=v->next;
printf("链表所有元素:");
while(q!=NULL)
{printf("%d ",q->data);q=q->next;}
printf("\n");
}
void main()
{LinkList L;
int temp;
int num,loc,flag=1;
char j;
int ch;
Node *node;
printf("本程序实现链式结构的线性表的操作。\n");
printf("可以进行插入,删除,定位,查找等操作。\n");
init_linklist(&L);
CreateFromTail(L); //生成单链表
Print(L);
while(flag)
{ printf("请选择:\n");
printf("1.显示所有元素\n"); //显示链表元素
printf("2.插入一个元素\n"); //插入链表元素
printf("3.删除一个元素\n"); //删除链表元素
printf("4.按关键字查找元素\n"); //按关键字查找
printf("5.按序号查找元素\n"); //按序号查找
printf("6.退出程序 \n"); //退出
scanf(" %c",&j);
switch(j)
{case '1':Print(L); break;
case '2':{printf("请输入元素(一个字符)和要插入的位置:\n");
printf("格式:数据,位置;例如:a,3\n");
scanf(" %d,%d",&ch,&loc); //输入要插入的元素和要插入的位置
temp=InsList(L,loc,ch); //插入
if(temp==ERROR) printf("插入失败!\n"); //插入失败
else printf("插入成功!\n"); //成功插入
Print(L);
break;
}
case '3':printf("请输入要删除的元素所在位置:");
scanf("%d",&loc); //输入要删除的节点的位置
temp=DelList(L,loc,&ch); //删除
if(temp==ERROR) printf("删除失败!\n"); //删除失败
else printf("成功删除了一个元素:%d\n",ch); //删除成功,显示该元素
Print(L);
break;
case '4':if(L->next==NULL) //链表为空
printf("链表为空!\n");
else{printf("请输入要查找的元素:");
scanf(" %d",&ch); //输入要查找的元素
ch=Locate(L,ch); //按关键字查找
if(ch==0) printf("没有找到该元素!\n"); //查找失败
else printf("该元素在链表的第%d个位置。\n",ch);
//成功查找,显示该元素位置
}
break;
case '5':if(L->next==NULL) //链表为空
printf("链表为空!\n");
else{printf("请输入要查找的位置:");
scanf("%d",&loc); //输入要查找的元素的位置
node=Get(L,loc); //按序号查找
if(node==NULL) printf("该位置不存在!\n"); //查找失败
else printf("第%d个元素是:%d\n",loc,node->data);
//成功查找,显示该元素
}
break;
default:flag=0;printf("程序结束,按任意键退出!\n");
}
}
getch();
}
五、心得体会:
1、如何使用不同方法建立链表
2、头插入法与尾插入法的不同
3、数据结构储存位置的分配
4、顺序插入与链表插入的不同