《软件技术基础》实验指导 实验一

线性表

说明

每个实验题目含有一个main函数和一些函数,与实验题目相关的基本运算的函数定义和main函数定义的代码在附录以及对应的文件夹中给出,供上机实验参考使用。对于每个题目,只需要根据题目要求设计算法,补充函数定义,然后对程序进行编译、调试。
不要在意代码风格

实验一 线性表

一、实验目的

  1. 熟悉线性表的顺序和链式存储结构
  2. 掌握线性表的基本运算
  3. 能够利用线性表的基本运算完成线性表应用的运算

二、实验内容

  1. 设有一个线性表E={e1, e2, … , en-1, en},设计一个算法,将线性表逆置,即使元素排列次序颠倒过来,成为逆线性表E’={ en , en-1 , … , e2 , e1 },要求逆线性表占用原线性表空间,并且用顺序表和单链表两种方法表示,分别用两个程序来完成。

  2. 已知由不具有头结点的单链表表示的线性表中,含有三类字符的数据元素(字母、数字和其他字符),试编写算法构造三个以循环链表表示的线性表,使每个表中只含有同一类的字符,且利用原表中的结点空间,头结点可另辟空间。

Tips

  1. 线性表的逆置,如逆置顺序表,要就地逆置,则首尾对调,直到中间;如逆置单链表,则从头到尾遍历并修改指针域的指向即可,但需主要如何修改指针指向的操作和头结点的处理,具体可以用循环实现或递归实现。

  2. 建立单链表存放数据元素,分别建立三个循环链表。再进行遍历,将各个元素按照分类插入新的循环链表即可,注意插入循环链表的操作。

Answer

1.1.1

//顺序表逆置的程序代码
#include<stdio.h>
#include<stdlib.h>
//#include<malloc.h>
//顺序表结构类型定义
typedef char datatype;
const int maxsize=1024;
typedef struct
{
    datatype data[maxsize];
    int last;
}sequenlist;
void create(sequenlist*&);
void print(sequenlist*);
void invert(sequenlist*);

//void main()
int main()
{
	sequenlist*L;
	create(L);//建立顺序表
	print(L);//输出顺序表
	invert(L);//调用顺序表逆值的函数
	print(L);//输出顺序表
	return 0;
}

//建立顺序表
void create(sequenlist*&L)
{
	L=(sequenlist*)malloc(sizeof(sequenlist));
	L->last=0;
	char ch;
	while((ch=getchar())!='*')
	{
		L->last++;
		L->data[L->last]=ch;
	}
}

//输出顺序表
void print(sequenlist*L)
{
	for(int i=1;i<=L->last;i++)
		printf("%2c",L->data[i]);
	printf("\n");
}

//顺序表逆置
void invert(sequenlist*L)
{
	int n=L->last/2;
	for(int i=1;i<=n;i++)
	{
		char temp=L->data[i];
		L->data[i]=L->data[L->last-i+1];
		L->data[L->last-i+1]=temp;
	}
}

1.1.2

//单链表逆置的程序代码
//#include<malloc.h>
#include<stdlib.h>
#include<stdio.h>
//单链表结构类型定义
typedef char datatype;
typedef struct node
{
	datatype data;
	struct node *next;
}linklist;
void create(linklist*&);
void print(linklist *);
void invert(linklist*);
void invert2(linklist*);

//void main()
int main()
{
	linklist*head;
	create(head);
	print(head);
	invert2(head);//调用单链表逆置的函数
	print(head);
	return 0;
}

//采用尾插法建立具有头结点的单链表
void create(linklist*&head)
{
	char ch;
	linklist *s,*r;
	head=(linklist*)malloc(sizeof(linklist));
	r=head;
	while((ch=getchar())!='*')
	{
		s=(linklist*)malloc(sizeof(linklist));
		s->data=ch;
		r->next=s;
		r=s;
	}
	r->next=NULL;
}

//输出单链表
void print(linklist *head)
{
	linklist*p=head->next;
	while(p!=NULL)
	{
		printf("%2c",p->data);
		p=p->next;
	}
	printf("\n");
}

//单链表逆置
//带头结点单链表逆置循环实现
void invert(linklist *head)
{
	linklist *p=head->next;//前一结点指针=头结点指针
	linklist *q=head->next->next;//当前结点指针=首结点指针
	linklist *t=NULL;//下一结点指针=空指针
	while(q!=NULL)//当(当前结点指针!=空指针)
	{
		t=q->next;//下一结点指针=指针域
		q->next=p;//指针域=上一节点指针
		p=q;  //前一结点指针=当前结点指针
		q=t;//当前结点指针=下一结点指针
	}
	head->next->next=NULL;//设置表尾 首结点指针=空指针
	head->next=p;//修改表头 头结点指针=前一节点指针
}

//带头结点单链表逆置递归实现
void invert2(linklist *head)
{
	linklist* invert2op(linklist*&,linklist*);//操作函数定义 引用头指针 传入首节点指针
	linklist* first=head->next;//首节点指针=头结点指针域
	invert2op(head,first);//操作函数实现递归

}
//带结点单链表逆置递归实现操作函数
linklist* invert2op(linklist*&head,linklist *first)
{
	linklist *p=first;//操作指针=首节点
	if(p==NULL)//如果是空链表
		return NULL;//返回空
	linklist *q=p->next;//下一结点指针=操作指针指针域
	if(q==NULL)//下一结点指针空即如果只剩一个节点
		return p;//返回当前节点
	else
			first=invert2op(head,q);//首节点指针=操作函数返回
	q->next=p;//下一结点指针域=操作指针
	p->next=NULL;//操作指挥指针域置空
	head->next=first;//头结点指针域=首节点
	return first;//操作函数返回 首节点指针
}

1.2

#include<stdio.h>
//#include<malloc.h>
#include<stdlib.h>
//链表结构类型定义
typedef char datatype;
typedef struct node
{
	datatype data;
	struct node *next;
}linklist;
void create(linklist*&);
void resolve(linklist*,linklist*,linklist*,linklist*);
void insert(linklist*,linklist*);
void print1(linklist*);
void print2(linklist*);
//void main()
int main()
{
	linklist*head,*letter,*digit,*other;
	create(head);
	print1(head);
	letter=(linklist*)malloc(sizeof(linklist));//建立3个空循环链表
	letter->next=letter;
	digit=(linklist*)malloc(sizeof(linklist));
	digit->next=digit;
	other=(linklist*)malloc(sizeof(linklist));
	other->next=other;
	resolve(head,letter,digit,other);//调用分解单链表的函数
	print2(letter);//输出循环链表
	print2(digit);
	print2(other);
	return 0;
}

//建立单链表
void create(linklist *&head)
{
	datatype x;
	linklist *s, *r;
//	head=(linklist*)malloc(sizeof(linklist));
	head=new linklist;
	r=head;
	while((x=getchar())!='$')
	{
		s=(linklist*)malloc(sizeof(linklist));
		s->data=x;
		r->next=s;
		r=s;
	}
	r->next=NULL;
}

//在循环链表中插入
void insert(linklist*h,linklist*p)//首结点指针 插入指针指向插入结点
{
	linklist *q=h;//操作指针=头结点
	while(q->next!=h)//当(操作指针所指向的结点指针域!=头结点)
		q=q->next;//操作指针=操作指针做指向的结点指针域
	q->next=p;//操作指针所指向的结点指针域=插入结点
	p->next=h;//插入结点的指针域=首结点
}

//输出单链表
void print1(linklist *head)
{
	linklist *p=head->next;
	while(p!=NULL)
	{
		printf("%c",p->data);
		p=p->next;
	}
	printf("\n");
}

//输出循环链表
void print2(linklist*head)
{
	linklist *p=head->next;
	while(p!=head)
	{
		printf("%c",p->data);
		p=p->next;
	}
	printf("\n");
}

//按字母、数字、其它字符分解单链表
void resolve(linklist*head,linklist*letter,linklist*digit,linklist*other)
{
	linklist *p=head->next;//操作指针=首结点
	while(p!=NULL)//当(操作指针!=空指针)
	{
		linklist *q=p->next;//缓存指针=操作指针的下一结点
		if(((p->data>='A')&&(p->data<='Z'))||((p->data>='a')&&(p->data<='z')))//如果是字母 
			insert(letter,p);//将操作指针指向的结点插入letter链表
		else if((p->data>='0')&&(p->data<='9'))
			insert(digit,p);
		else
			insert(other,p);
		p=q;//操作指针=缓存指针
	}
}
posted @ 2017-10-24 23:36  VanLion  阅读(648)  评论(0编辑  收藏  举报