利用线性表的链式存储结构,设计一组输入数据能够对单链表进行如下操作:
. 初始化一个带表头结点的空链表;
. 创建一个单链表是从无到有地建立起一个链表,即一个一个地输入各结点数据,并建立起前后相互链接的关系。又分为逆位序(插在表头)输入n 个元素的值和正位序(插在表尾)输入n 个元素的值;
. 插入结点可以根据给定位置进行插入(位置插入),也可以根据结点的值插入到已知的链表中(值插入), 且保持结点的数据按原来的递增次序排列,形成有序链表。
. 删除结点可以根据给定位置进行删除(位置删除),也可以把链表中查找结点的值为搜索对象的结点全部删除(值删除);
. 输出单链表的内容是将链表中各结点的数据依次显示,直到链表尾结点;
其它的操作算法描述略。
. 编写主程序,实现对各不同的算法调用。
解决方案:
1.启动VC++;
2.新建工程/Win32 Console Application,选择输入位置:如“d:\”,输入工程的名称:如“linklistDemo”;按“确定”按钮,选择“An Empty Project”,再按“完成”按钮,
3.新建pubuse.h 文件,代码如下;
#ifndef PUBUSE_H
#define PUBUSE_H
#pragma once
#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等*/
#include<limits.h> /* INT_MAX 等*/
#include<stdio.h> /* EOF(=^Z 或F6),NULL */
#include<iostream>
#include<istream>
using namespace std;
#include<stdlib.h> /* atoi() */
#include<io.h> /* eof() */
#include<math.h> /* floor(),ceil(),abs() */
#include<process.h> /* exit() */
/* 函数结果状态代码*/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/* #define OVERFLOW -2 因为在math. h 中已定义OVERFLOW 的值为3,故去掉此行*/
typedef int Status; /* Status 是函数的类型,其值是函数结果状态代码,如OK 等*/
typedef int Boolean; /* Boolean 是布尔类型,其值是TRUE 或FALSE */
typedef int ElemType; //定义ElemType为 int 型
#endif
4. 新建文件/C/C++ Header File,选中“添加到工程的复选按钮”,输入文件名“linklistDef.h”,按“确定”按钮,在显示的代码编辑区内输入程序;
typedef struct LNode
{
ElemType data; //节点的数据域
struct LNode* next; //节点的指针域
}LNode, * LinkList;//定义结构体,LinkList指向LNode
5. 新建文件/C/C++ Header File,选中“添加到工程的复选按钮”,输入文件名“linklistAlgo.h”,按“确定”按钮,在显示的代码编辑区内输入程序;
Status ListInit_Link(LinkList &L)
{
L = new LNode;
L->next = NULL;
return OK ;
}
//创建前插法单链表,输入元素
void CreateList_H(LinkList &L, int m)
{
L=new LNode;
L->next=NULL;
for(int i=0;i<m;++i)
{
LinkList p = new LNode;
cin >> p->data ;
p->next = L->next;
L->next = p;
}
}
//创建后插法单链表,输入元素
void CreateList_R(LinkList &L,int n)
{
LNode *list,*p;
L=new LNode;
L->next=NULL;
list=L;
for(int i=0;i<n;++i)
{
LinkList p=new LNode;
cin>>p->data;
p->next=NULL;p->next=list->next;list->next=p;
list=p;
}
}
//输出
Status OutputList_Link(LinkList &L)
{
LinkList p = L->next;
if (p == NULL)
{
cout << " 此链表为空链表" << endl;
}
else {
cout << " ";
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
cout<<endl;
}
}
//求表长
int GetLength_Link(LinkList &L)
{
int i = 0;
LinkList p = L;
while (p->next != NULL)
{
i++;
p = p->next;
}
return i;
}
//查找第i个位置的元素
Status SearchIndex_Link(LinkList L, int index)
{
int length1 = GetLength_Link(L);
if (index <= 0 || index > length1)
cout << " 您输入的索引超过了线性表的长度范围。" << endl;
LinkList p = L;
int i = 0;
while (p->next != NULL)
{
p = p->next;
i++;
if (i == index)
{
cout << " 第" << index<<"个" << "位置的元素为" << p ->data << endl;
}
}
}
//查找值为e的结点
Status HasList_Link(LinkList L, ElemType e)
{
LinkList p = L->next;
int i=1;
while (p != NULL)
{
if (p->data == e)
break;
else
{
i++;
p = p->next;
}
}
int length4;
length4=GetLength_Link(L);
if (i>0 && i<=length4) {
cout << " 元素" << e << "存在于此线性表中,其位置是" << i << endl;
}
else {
cout << " 元素" << e << "不存在于此线性表中" << endl;
}
}
//删除元素
Status DeleteElem_Link(LinkList &L, ElemType e)
{
LinkList p = L;
LinkList q = NULL;
while (p->next != NULL) {
if (p->next->data == e)
{
q = p->next;
p->next = p->next->next;
break;
}
p = p->next;
}
if (q != NULL)
{
delete q;
cout << " 元素" << e << "删除成功。" << endl;
}
else
{
cout << " 元素" << e << "不存在于此线性表中,无法删除。" << endl;
}
}
//删除第i个元素
Status DeleteIndex_Link(LinkList &L, int i)
{
int length2 = GetLength_Link(L);
if (i <= 0 || i > length2)
{
cout << " 您输入的索引超过了线性表的长度范围。" << endl;
}
else
{
LinkList p = L;
LinkList q = NULL;
int num = 0;
while (p->next != NULL)
{
num++;
if (num == i) {
q = p->next;
p->next = p->next->next;
break;
}
p = p->next;
}
if (q != NULL)
{
delete q;
cout << " 删除成功。" << endl;
}
}
}
//在指定位置插入元素
Status ListLocateInsert_Link(LinkList &L, int i, ElemType e)
{
LinkList p = L;
LinkList q = new LNode;
int num1 = 0;
while (p->next != NULL)
{
num1++;
if (num1 == i) {
q->next = p->next;
p->next = q;
q->data = e;
break;
}
p = p->next;
}
cout <<" "<< e << "插入成功" << endl;
}
//按元素名插入元素
Status ListElemInsert_Link(LinkList &L, ElemType i, ElemType e)
{
LinkList p = L;
LinkList q = new LNode;
if(p != NULL)
{
while (p != NULL)
{
if (p->data == i) {
q->next = p->next;
p->next = q;
q->data = e;
break;
}
p = p->next;
}
cout <<" "<< e << "插入成功" << endl;
}
else
cout << " 您输入的特定元素" << i <<"不存在此表中,无法插入" << endl;
}
//生成有序链表
void ListSort_L(LinkList &L)
{
LNode *p, *pre;
LNode *s;
p = L->next;
s = p->next; //s指向要进行操作的链表
p->next = NULL; // 构成一个只含一个数据结点的有序表,初始时只有一个元素
while (s!=NULL)
{
p = s; //p指向当前链表要进行操作的元素
s = s->next; //s继续指向链表的下一个结点
pre = L;
while (pre->next != NULL && pre->next->data < p->data)
{
pre = pre->next; //在有序表中找到插入位置
}
p->next = pre->next ; //在有序表的相应位置插入
pre->next = p;
}
}
//销毁链表
Status DestroyList_L(LinkList&L)
{
LNode *p;
while(L)
{
p=L;
L=L->next;
delete p;
}
cout << " 销毁成功" << endl;
}
6. 新建文件/C++ Source File,选中“添加到工程的复选按钮”,输入文件名“linklistUse.cpp”,按“确定” 按钮,在显示的代码编辑区内输入程序,实现菜单制作与输入传值传参;
#include"pubuse.h"
#include"LinkListDef.h"
#include"LinkListAlgo.h"
int main()
{
LinkList L ;
Status ListInit_Link(LinkList &L);
ListInit_Link(L);
cout << " *********************************实验02 线性表的链式实现*******************************" <<endl<<endl;
cout << " 组别:第十组"<< endl;
cout << " 小组成员:余新亚 廖丽华 冯安颖 李欣怡 胡锦欣 李响 "<<endl<<endl;
cout << " --------------------------------------线性表操作----------------------------------------" << endl<<endl;
cout << "\t0.退出单链表 " << "\t\t";
cout << "\t1.前插法输入元素 " << endl << endl;
cout << "\t2.后插法输入元素 " << "\t\t";
cout << "\t3.输出单链表 " << endl << endl;
cout << "\t4.返回单链表长度 " << "\t\t";
cout << "\t5.根据索引查找元素 " << endl << endl;
cout << "\t6.判断单链表中是否包含指定元素 " << "\t\t";
cout << "\t7.根据元素名称删除元素 " << endl << endl;
cout << "\t8.根据索引删除元素 " << "\t\t";
cout << "\t9.在指定位置前插入元素 " << endl << endl;
cout << "\t10.在特定元素后插入元素 " << "\t\t";
cout << "\t11.生成有序链表 " << endl << endl;
cout << "\t12.销毁单链表 " << endl << endl;
while (1)
{
cout << " 请按下您需要操作的数字键:" ;
int s;
cin >> s;
switch (s)
{
case 0:
cout << "欢迎下次使用!" << endl;
return 0;
break;
case 1:
cout << " 请输入您要输入的元素的个数(前插法):";
int num1;
cin >> num1;
cout<<" 请输入您需要输入的"<<num1<<"个数字(注意输入完成后按下Enter键以示确认):";
cout << " ";
CreateList_H(L, num1) ;
break;
case 2:
cout << " 请输入您要输入的元素的个数(后插法):";
int num2;
cin >> num2;
cout<<" 请输入您需要输入的"<<num2<<"个数字(注意输入完成后按下Enter键以示确认):";
cout << " ";
CreateList_R(L,num2);
break;
case 3:
cout << " 此线性表的元素如下:" << endl;
OutputList_Link(L);
break;
case 4:
int length;
length = GetLength_Link(L);
cout << " 此线性表的表长为" << length << endl;
break;
case 5:
cout << " 请输入您要查找的的位置:" ;
int index1;
cin >> index1;
SearchIndex_Link(L, index1);
break;
case 6:
cout << " 请输入您要核对的元素:" ;
ElemType element2;
cin >> element2;
HasList_Link(L, element2);
break;
case 7:
cout << " 请输入您要删除的元素:";
ElemType element3;
cin >> element3;
DeleteElem_Link(L, element3);
break;
case 8:
cout << " 请输入您要删除元素的位置:";
int index2;
cin >> index2;
DeleteIndex_Link(L, index2);
break;
case 9:
cout << " 请输入您要插入的位置:" ;
int address;
cin >> address;
int length3 ;
length3=GetLength_Link(L);
if (address<= 0 || address > length3)
{
cout << " 您想要插入的位置超过了线性表的长度范围。" << endl;
}
else
{
cout << " 请输入您想要插入的元素:" ;
ElemType e;
cin >> e;
ListLocateInsert_Link(L, address, e);
}
break;
case 10:
cout<<" 请先输入您需要插入对应的特定元素:" ;
ElemType a,b;
cin >> a;
cout << " 请先输入您需要插入的元素:" ;
cin >> b ;
ListElemInsert_Link(L,a,b);
break;
case 11:
cout << " 原链表如下:" << endl;
OutputList_Link(L);
cout << " 有序链表生成成功,结果如下:" << endl;
ListSort_L(L);
OutputList_Link(L);
break;
case 12:
DestroyList_L(L);
break;
default:
cout << " 您输入的数字键有误,请重新输入0~11的数字键" << endl;
}
}
return 0;
}
7.最后构件、调试、运行
最后就大功告成啦!!!
努力写好代码的第一天噎,欢迎评论区留言指正