数据结构实验-线性表的基本操作

实验内容:

1.首先要对链表和顺序表存储结构进行定义,链表定义结点数据域和指针域,顺序表定义存储空间基地址和长度。然后对链表和顺序表进行初始化,初始化就是构造一个空的表。

2.输入学生信息和在指定位置插入学生信息都是用ListInsert函数进行插入,算法一样。

3.显示学生信息是将每一个学生信息在表中进行取值然后进行输出,顺序表取值可以直接通过数组下标定位第i个元素值,链表取值不能随机访问,需要从链表的首元结点出发,顺着链域next逐个结点向下访问。

4.在链表查询时,先输入学生姓名,利用search函数进行查找。先初始化,用指针p指向首元结点,用strcmp函数对p所指结点数据域的姓名值与输入的姓名进行对比,如果相同返回结点地址p,然后将结点p的数据域进行输出。

5.显示指定位置学生信息和显示学生信息算法相同,显示学生信息是显示所有的信息,显示指定位置的学生信息是显示单个学生信息,都是顺序表的取值操作。

5.在链表插入时,先录入要插入的位置,然后用input函数将数据存在c结点中,再用ListInsert函数将结点插入链表,先查找插入位置的前一个结点,将指针p指向该结点。生成一个新节点s,将结点s的数据域置为输入的c结点,将 结点s的指针域指向下一个结点,将结点p的指针域指向结点s。

7.删除指定位置的学生记录是线性表的删除操作。顺序表删除主要是被删除元素之后元素前移,然后将表长减一。链表删除时先找到要删除元素前一个元素,指针p指向该结点,临时保存被删除结点的地址以备释放,将要删除结点的前驱结点指针域指向要删除结点的直接后继结点,释放删除结点空间。

程序代码LinkList

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
    char no[8];   //8位学号
    char name[20]; //姓名
    int score;     //成绩
}Student;

typedef struct LNode{
     Student   data;       //数据域
     struct LNode  *next;   //指针域
}LNode,*LinkList;

int IniList(LinkList L)//单链表初始化 
{
    L=(struct LNode*)malloc(sizeof(struct LNode));//生成新结点为头结点,头指针L指向头结点
    L->next=NULL;//头结点指针域置空;
    return 1;
}

int GetElem(LinkList L,int i,Student *e)//单链表取值 
{
     LinkList p;//建立新结点
     p=L->next;//指向L->next
     int j=1;
     while(p&&j<i)//向后扫描,直到p为空或者指向第i元素
     {
         p=p->next;//指向下一结点
         ++j;//计数器加一
     }
     if(!p||j>i) return 0;//判断i是否合法
     *e=p->data;//取第i个结点数据域
     return 1;
}

int Search(LinkList L,char str[],Student *e)//单链表查找 
{
    LinkList p;
    p=L->next;
    while(p)//向后扫描,直到p为空
    {
        if(strcmp(p->data.name,str)==0){//逐个比较直到找出相同的为止
            *e=p->data;
            return 1;
        }

        p=p->next;//指向下一结点
    }
   return 0;
}

int ListInsert(LinkList L,int i,Student e)//插入学生信息 
{
    LinkList p,s;
    p=L;
    int j=0;
    while(p&&j<i-1)
    {
        p=p->next;//查找第i-1个结点,p指向该结点
        ++j;
    }
    if(!p||j>i-1)return 0;
    s=(struct LNode*)malloc(sizeof(LNode));//生成新结点
    s->data=e;//结点*s的数据域置为e
    s->next=p->next;//结点*s的指针域指向结点ai
    p->next=s;//结点*p的指针域指向结点*s
    return 1;
}
int ListDelete(LinkList p,int i)//删除学生信息 
{
    int j=0;
    while((p->next)&&(j<i-1))//查找第i-1个结点,p指向该节点
    {
        p=p->next;
        ++j;
    }
    if(!(p->next)||(j>i-1))return 0;//判断删除位置是否合理
    LinkList q;//生成新结点
    q=p->next;//保存被删结点的地址以便于释放
    p->next=q->next;//改变删除结点前驱结点的指针域
    free(q);//释放删除结点空间
    return 1;
}

void Input(Student *e)//输入学生信息 
{
    printf("学号:");	scanf("%s",e->no);
	printf("姓名:");	scanf("%s",e->name);
	printf("成绩:");	scanf("%d",&e->score);
	printf("输入完成\n\n");
}
void Output(Student *e)//输出学生信息 
{
    printf("学号:%s\n姓名:%s\n成绩:%d\n\n",e->no,e->name,e->score);
}
int main()
{
    LNode L;
    LinkList p;
    Student a,b,c,d,f;
    char s[20];
    int i,id1,id2,id3;
    printf("\n********************************\n\n");
	printf("1. 构造链表\n");
	printf("2. 录入学生信息\n");
	printf("3. 显示学生信息\n");
	printf("4. 输入姓名,查找该学生\n");
	printf("5. 显示某位置该学生信息\n");
	printf("6. 在指定位置插入学生信息\n");
	printf("7. 在指定位置删除学生信息\n");
	printf("8. 统计学生个数\n");
	printf("0. 退出\n");
	printf("\n********************************\n\n");
	int x,choose=-1;
	while(choose!=0)
	{
		printf("请选择:");
		scanf("%d",&choose);
		switch(choose)
		{
		    case 1:
					if(IniList(p))
						printf("成功建立链表\n\n");
					else
						printf("链表建立失败\n\n");
					break;
			case 2:
					printf("请输入要录入学生信息的人数:");
					scanf("%d",&x);
					for(i=1;i<=x;i++)
					{
						printf("第%d个学生:\n",i);
						Input(&a);
						ListInsert(&L,i,a);
					}
					break;
			case 3:
					for(i=1;i<=x;i++)
					{
						GetElem(&L,i,&b);
						Output(&b);
					}
					break;
			case 4:
			            printf("请输入要查找的学生姓名:");
			            scanf("%s",s);

                    if(Search(&L,s,&f))
						Output(&f);
					else
						printf("对不起,查无此人\n");
					puts("");

					break;
			case 5:
					printf("请输入要查询的位置:");
					scanf("%d",&id1);
					GetElem(&L,id1,&c);
					Output(&c);
					break;
			case 6:
					printf ("请输入要插入的位置:");
					scanf("%d",&id2);
					printf("请输入学生信息:\n");
					Input(&d);
					if(ListInsert(&L,id2,d))
					{
						x++;
						printf("插入成功\n");
						puts("");
					}
					else
					{
						printf("插入失败\n");
						puts("");
					}
					break;
			case 7:
					printf("请输入要删除的位置:");
					scanf("%d",&id3);
					if(ListDelete(&L,id3))
					{
						x--;
						printf("删除成功\n");
						puts("");
					}
					else
					{
						printf("删除失败\n");
						puts("");
					}
					break;
			case 8:
					printf("已录入的学生个数为:%d\n\n",x);
					break;
		}
	}
    return 0;
}

程序代码SqList

#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 100
 typedef struct
 {
	char no[8];//8位学号 
	char name[20];//姓名 
	int score;//成绩 
}Student;

typedef struct{
	Student *elem;  //指向数据元素的基地址
	int length; //线性表的当前长度 
}SqList;

int creat(SqList &L)//构造一个空的顺序表L ,顺序表的初始化 
{
	L.elem=(Student*)malloc(sizeof(Student)*MAXSIZE); //分配大小为MAXSIZE的数组空间
	if(!L.elem) printf("分配失败");//存储分配失败
	L.length=0;
	printf("分配内存空间成功!");
	return 1; 
}
Student GetElem(SqList L,int i)  //位置序号i的取值 
{
	return L.elem[i]; 
}

int LocateElem(SqList L)  //查找学生信息 
{
	int t=0;
    char s[20];
    printf("请输入要查找的学生姓名:");
    scanf("%s",s);
    int i;
    for(i=1;i<=L.length;i++)
    {
        if(strcmp(L.elem[i].name,s)==0)
            t=i;
    }
    return t;
}

int ListInsert(SqList &L,int i,Student e)//插入学生信息 到表中指定位置 
{  
    int j;
    if((i<1)||(i>L.length+1))  printf("错误");
    if(L.length==MAXSIZE)      printf("错误");
    for(j=L.length-1;j>=i-1;j--)
    {
        L.elem[j+1]=L.elem[j];
    }
    L.elem[i-1]=e;
    ++L.length;
    return 1;
}

int ListDelete(SqList &L,int i)//删除指定位置的学生信息 
{
    int j;
    if((i<1)||(i>L.length))  printf("错误,i值不合法。");
    for(j=i;j<=L.length;j++)
    {
        L.elem[j]=L.elem[j+1];
    }
    --L.length;
    return 1;
}

void input(Student *e)//输入学生信息 
{
	printf("学号:");	scanf("%s",e->no);
	printf("姓名:");	scanf("%s",e->name);
	printf("成绩:");	scanf("%d",&e->score);
	printf("输入完成\n\n");
}

void Output(Student *e)//输出函数
{
	printf("学号:%s\n姓名:%s\n成绩:%d\n\n",e->no,e->name,e->score);
}
int main()
{
    SqList L;
    Student a,b,c;
    printf("\n********************************\n\n");
	printf("1. 顺序表初始化                 *\n");
	printf("2. 录入学生信息                 *\n");
	printf("3. 显示学生信息                 *\n");
	printf("4. 输入姓名,查找该学生         *\n");
	printf("5. 显示某位置该学生信息         *\n");
	printf("6. 在指定位置插入学生信息       *\n");
	printf("7. 在指定位置删除学生信息       *\n");
	printf("8. 统计学生个数                 *\n");
	printf("0. 退出                         *\n");
	printf("\n********************************\n\n");
    int x,choose,i,d=0,id1,id2,id3;

    while(1)
    {
        printf("请选择");
        scanf("%d",&choose);
        if(choose==0)break;
        switch(choose)
        {
            case 1:if(creat(L))
						printf("成功建立顺序表\n\n");
					else
						printf("顺序表建立失败\n\n");
					break;
            case 2:printf("请输入要录入学生的人数(小于100):");
					scanf("%d",&x);
					for(i=1;i<=x;i++)
					{
						printf("第%d个学生:\n",i);
						input(&L.elem[i]);
					}
					L.length=x;
					puts("");
					break;
            case 3:for(i=1;i<=x;i++)
					{
						a=(Student)(GetElem(L,i));
						Output(&a);
					}
					break;
            case 4:

					d=LocateElem(L);
					if(d>0)
						Output(&L.elem[LocateElem(L)]);
					else
						puts("对不起,查无此人\n");
					printf("");
					break;
            case 5:
					printf("请输入要查询的位置:");
					scanf("%d",&id1);
					b=GetElem(L,id1);
					Output(&b);
					break;
            case 6:
					printf ("请输入要插入的位置:");
					scanf("%d",&id2);
					printf("请输入学生信息:\n");
					input(&c);
					if(ListInsert(L,id2,c))
					{
						x++;
						printf("插入成功\n");
						puts("");
					}
					else
					{
						printf("插入失败");
						puts("");
					}
					break;
             case 7:
					printf("请输入要删除的位置:");
					scanf("%d",&id3);
					if(ListDelete(L,id3))
					{
						x--;
						printf("删除成功");
						puts("");
					}
					else
					{
						printf("删除失败");
						puts("");
					}
					break;
            case 8:
					printf("已录入的学生个数为:%d\n\n",L.length);
					break;
        }
    }
}


猜你喜欢

转载自blog.csdn.net/m0_54570435/article/details/130399638