线性结构的表示和实现--我的图书馆
/*
Name: linklist.h
Copyright:
Author:
Date: 21-03-05 20:21
Description:
*/
#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED
#include "ds.h" //for Status,OK ...
#ifndef ElemType
#define ElemType int /* 数据元素类型默认为 int */
#define ELEMTYPE_TAG
#endif
/**********************************************************
* 单链表的存储结构定义
***********************************************************/
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
/**********************************************************
* 单链表的基本操作声明
***********************************************************/
//创建并初始化为空表
Status InitList(LinkList &L);
//销毁整个表(从此之后不再可用)
Status DestroyList(LinkList &L);
//将表L置空
Status ClearList(LinkList &L);
//判断表L是否为空表
bool ListEmpty(LinkList L);
//求表L的长度
int ListLength(LinkList L);
//取表L中的第i个元素,并用e返回. 操作成功返回OK,失败时返回ERROR
Status GetElem(LinkList L, int i, ElemType &e);
template <typename T> bool equal(T a, T b)
{
return a==b;
}
//在表L中定位元素e首次出现的位置. 操作成功返回位序,失败时返回0
// compare(a,b) 为比较函数,匹配时返回true,否则返回false
// 这里默认使用equal进行比较
int LocateElem(LinkList L, ElemType e,
bool (*compare)(ElemType,ElemType)=equal<ElemType>);
//在表L中插入第i个元素e. 操作成功返回OK,失败时返回ERROR
Status ListInsert(LinkList &L, int i, ElemType e);
//删除表L中第i个元素,结果用e返回. 操作成功返回OK,失败时返回ERROR
Status ListDelete(LinkList &L, int i, ElemType &e);
//遍历表L,对每个元素调用visit(x).
Status ListTraverse(LinkList L, Status (*visit)(ElemType));
/**********************************************************
* 单链表的基本操作的实现
***********************************************************/
//创建并初始化为空表
Status InitList(LinkList &L)
{
// TODO (#1#): 创建空表
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
return ERROR;
//-------------------------------------
}
//销毁整个表(从此之后不再可用)
Status DestroyList(LinkList &L)
{
// TODO (#1#): 销毁表
free(L);
return ERROR;
//-------------------------------------
}
//将表L置空
Status ClearList(LinkList &L)
{
// TODO (#1#): 清空表
return ERROR;
//-------------------------------------
}
//判断表L是否为空表
bool ListEmpty(LinkList L)
{
// TODO (#1#): 链表判空
if(L->next==NULL)
return true;
else
return false;
//-------------------------------------
}
//求表L的长度
int ListLength(LinkList L)
{
// TODO (#1#): 链表求长度
int count=0;
while ( L->next){
count++;
L=L->next;
}
return count;
//-------------------------------------
}
//取表L中的第i个元素,并用e返回. 操作成功返回OK,失败时返回ERROR
Status GetElem(LinkList L, int i, ElemType &e)
{
// TODO (#1#): 实现取元素GetElem(L,i,&e)
LinkList p;
p=L->next;
int j=1;
while(p&&j<i-1){
p=p->next;
j++;
}
if(!p||j>i-1)
return ERROR;
e=p->data;
return ERROR;
//-------------------------------------
}
//在表L中定位元素e首次出现的位置. 操作成功返回位序,失败时返回0
// compare(a,b) 为比较函数,匹配时返回true,否则返回false
int LocateElem(LinkList L, ElemType e, bool (*compare)(ElemType,ElemType))
{
// TODO (#1#): 在表中定位元素e,用compare(a,b)匹配元素
LinkList p;
int j;
p = L->next; j = 1;
while(p!=NULL) {
if( compare(p->data,e) ) return j+1;
p=p->next;
}
return 0;
//-------------------------------------
}
//在表L中插入第i个元素e. 操作成功返回OK,失败时返回ERROR
Status ListInsert(LinkList &L, int i, ElemType e)
{
// TODO (#1#): 在链表中插入元素
LinkList p=L,s;
int j=0;
p=L;
while(p&&j<i-1){
p=p->next;
j++;
}
if(!p||j>i-1)
return ERROR;
s=(LinkList) malloc (sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return ERROR;
//-------------------------------------
}
//删除表L中第i个元素,结果用e返回. 操作成功返回OK,失败时返回ERROR
Status ListDelete(LinkList &L, int i, ElemType &e)
{
// TODO (#1#): 在链表中删除元素
LinkList p,q;
p=L ;
int j=0;
while (p->next&&j<i-1){
p=p->next;
++j;
}
q=p->next;
p->next=q->next;
e=q->data;
free(q);
return ERROR;
//-------------------------------------
}
//遍历表L,对每个元素调用visit(x).
Status ListTraverse(LinkList L, Status (*visit)(ElemType))
{
LinkList p = L->next;
while ( p ) {
if ( visit(p->data)==ERROR ) return ERROR;
p = p->next;
}
return OK;
}
#ifdef ELEMTYPE_TAG
#undef ElemType
#undef ELEMTYPE_TAG
#endif
#endif // LINKLIST_H_INCLUDED
/****************************************************
@title: 数据结构实验
@name: <实验2-2> 线性表的链式存储结构
@object:
[实验目的]
单链表的存储结构及其基本操作的实现
[实验提示]
1. 在linklist.h中实现单链表的基本操作
2. 在dsp0202.cpp中编写适当的代码,进行测试
@include:
linklist.h [*]
单链表的实现
@usage:
请查看"TO-DO列表",根据要求完成代码
@copyright: BTC 2005, Zhuang Bo
@author: Zhuang Bo
@date: 2005
@description:
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "ds.h"
#define ElemType int //数据元素的类型
Status print(ElemType e); // 打印数据元素的方法
bool equal(ElemType a, ElemType b); //比较两个元素相等的方法
#include "linklist.h"
//打印链表内容
void PrintLinkList(LinkList L);
int main()
{
LinkList L;
//1)初始化链表
InitList(L);
//2)插入一些元素: 12,23,34,45
ListInsert(L,1,12);
ListInsert(L,1,23);
ListInsert(L,1,34);
ListInsert(L,1,45);
//3)打印链表信息
printf("\n开始时链表内容\n");
PrintLinkList(L);
printf("ListLength(L) : %d\n", ListLength(L));
printf("ListEmpty(L) : %d\n", ListEmpty(L));
//4)链表插入
printf("\n请输入一个元素:");
ElemType x;
read(x);
printf("插入开头:");
ListInsert(L,1,x);
PrintLinkList(L);
printf("插入末尾:");
ListInsert(L,ListLength(L)+1,x);
PrintLinkList(L);
//5)链表删除
printf("\n请选择删除第i(1..%d)个元素:", ListLength(L));
int i;
read(i);
ElemType e;
if ( ListDelete(L,i,e)==OK ) {
Status print(ElemType e); //声明print(e)函数
printf("删除"); print(e);
printf("成功\n");
} else
printf("删除失败.\n");
printf("链表内容:");
PrintLinkList(L);
//6)元素定位
printf("\n请输入一个元素以便定位:");
read(x);
i = LocateElem(L,x);
if ( i!=0 ) {
printf("该元素是表中的第%d个元素.\n",i);
} else
printf("该元素在表中不存在.\n");
//7)清空链表
ClearList(L);
printf("\n最后链表内容\n");
PrintLinkList(L);
printf("ListLength(L) : %d\n", ListLength(L));
printf("ListEmpty(L) : %d\n", ListEmpty(L));
//8)销毁链表
DestroyList(L);
system("PAUSE");
return 0;
}
// 打印数据元素的方法
Status print(ElemType e)
{
printf("%5d",e);
return OK;
}
//比较两个元素相等的方法
bool equal(ElemType a, ElemType b)
{
return a==b;
}
//打印链表内容
void PrintLinkList(LinkList L)
{
ListTraverse(L,print); //遍历链表并print()每个元素
printf("\n");
}