编写一个程序2-2.cpp,实现单链表的各种基本运算(假设单链表的元素类型为char),并在此基础上设计一个程序2-2.cpp,完成如下功能:
(1)初始化单链表h;
(2)采用尾插法依次插入元素a,b,c,d,e;
(3)输出单链表h;
(4)输出单链表h的长度;
(5)判断单链表h是否为空;
(6)判断单链表h的第3个元素;
(7)输出元素a的位置;
(8)在第4个元素位置上插入元素f;
(9)输出单链表h;
(10)删除h的第3个元素;
(11)输出单链表h;
(12)释放单链表h.
#include <iostream>
#include <cstdio>
#include <malloc.h>
using namespace std;
typedef struct LNode
{
char data;
struct LNode *next;
} LinkList;
void InitList(LinkList *&L)
{
L=(LinkList *)malloc(sizeof(LinkList));
L->next=NULL;
}
void DestroyList(LinkList *&L)
{
LinkList *p=L,*q=p->next;
while (q!=NULL)
{
free(p);
p=q;
q=p->next;
}
free(p);
}
bool ListEmpty(LinkList *L)
{
return(L->next==NULL);
}
int ListLength(LinkList *L)
{
LinkList *p=L;int i=0;
while (p->next!=NULL)
{
i++;
p=p->next;
}
return(i);
}
void DispList(LinkList *L)
{
LinkList *p=L->next;
while (p!=NULL)
{
printf("%c ",p->data);
p=p->next;
}
printf("\n");
}
bool GetElem(LinkList *L,int i,char &e)
{
int j=0;
LinkList *p=L;
while (j<i && p!=NULL)
{ j++;
p=p->next;
}
if (p==NULL)
return false;
else
{ e=p->data;
return true;
}
}
int LocateElem(LinkList *L,char e)
{ int i=1;
LinkList *p=L->next;
while (p!=NULL && p->data!=e)
{ p=p->next;
i++;
}
if (p==NULL)
return(0);
else
return(i);
}
bool ListInsert(LinkList *&L,int i,char e)
{
int j=0;
LinkList *p=L,*s;
while (j<i-1 && p!=NULL)
{ j++;
p=p->next;
}
if (p==NULL)
return false;
else
{ s=(LinkList *)malloc(sizeof(LinkList));
s->data=e;
s->next=p->next;
p->next=s;
return true;
}
}
bool ListDelete(LinkList *&L,int i,char &e)
{
int j=0;
LinkList *p=L,*q;
while (j<i-1 && p!=NULL)
{ j++;
p=p->next;
}
if (p==NULL)
return false;
else
{ q=p->next;
if (q==NULL)
return false;
e=q->data;
p->next=q->next;
free(q);
return true;
}
}
int main()
{
LinkList *L;
char e;
cout<<"(1)初始化单链表h"<<endl;
InitList(L);
cout<<"(2)依次采用尾插法插入a,b,c,d,e元素"<<endl;
ListInsert(L,1,'a');
ListInsert(L,2,'b');
ListInsert(L,3,'c');
ListInsert(L,4,'d');
ListInsert(L,5,'e');
cout<<"(3)输出单链表h:";
DispList(L);
cout<<"(4)单链表h长度="<<ListLength(L)<<endl;
cout<<"(5)判断单链表是否为空?";
if(ListEmpty(L))
cout<<"单链表为空!"<<endl;
else
cout<<"单链表非空!"<<endl;
GetElem(L,3,e);
cout<<"(6)单链表h的第3个元素为"<<e<<endl;
cout<<"(7)元素a的位置="<<LocateElem(L,'a')<<endl;
cout<<"(8)在第4个元素位置上插入f元素"<<endl;
ListInsert(L,4,'f');
cout<<"(9)输出单链表h:";
DispList(L);
cout<<"(10)删除h的第3个元素"<<endl;
ListDelete(L,3,e);
cout<<"(11)输出单链表h:";
DispList(L);
cout<<"(12)释放单链表h"<<endl;
DestroyList(L);
return 0;
}
运行结果:
思路:
要求对线性表进行各种操作实现初始化,插入元素,删除元素以及判断并输出线性表的性质等功能,首先需要一个类或一个结构体,并且定义char型数组用来存储数据,定义基本运算,最后在main函数中调用各个函数实现对线性表的操作。
算法函数分析:
定义初始化函数,插入元素函数,输出函数,判断是否为空函数,输出元素位置函数,删除元素函数,释放线性表函数,并且在main函数中调用上列函数,实现对线性表的初始化,尾差法插入元素,输出线性表,判断线性表是否为空,输出元素位置,删除元素,释放元素的操作。
输入输出:
输入线性表元素,输出线性表的长度,元素位置和操作完成后线性表的元素。
心得体会:
通过编写这两个程序,我知道了顺序表与单链表的差别:
顺序表存储位置是相邻连续的,可随机访问表内元素,一个顺序表在使用前必须指定起长度,并且分配内存就不可以再进行动态的更改,缺点是不方便进行插入删除操作。
链表是通过指针来描述元素关系的一种数据结构,有数据域和指针域,可以动态的改变数据的长度,插入删除简单无需数据移动,只需改变指针,缺点是不能随机访问元素,必须从表头开始,一步一步搜索元素。
如果一个数组在使用中,查询比较多,而插入,删除数据比较少,并且数组的长度不变时,选顺序表比较合理。如果插入,删除,长度不定的数组,可以选链表。