代碼:
主類:
/****************************************************
@title: 數據結構實驗
@name: <實驗2-1> 線性表(順序表)的應用--我的圖書館
@object:
[實驗目的]
應用線性表解決問題.
有若干圖書,借出的書需要登記下來.
用兩個線性表分別保存現有圖書和借書信息,
並實現增加新書,借書,還書,打印等功能.
學習命令式程序界面的編寫方法.
[實驗提示]
1. 在book.h中描述了描述書的Book類型,還有
幾個有關函數函數可以調用.
2. 在sqlist.h中完成順序表的各種操作.
3. 借書時,輸入書名,若有存書,則從存書表中
刪除,插入借書表.
4. 還書時,輸入書名,若借過此書,則從借書表
中刪除,插入存書表.
@include:
用到的頭文件
@usage:
請查看"TO-DO列表",根據要求完成代碼
@copyright: BTC 2005, Zhuang Bo
@author: Zhuang Bo
@date: 2005
@description:
*****************************************************/
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#include "book.h"
#define ElemType Book //使用Book作爲線性表元素的類型
#include "sqlist.h"
SqList s; //存書表
SqList b; //借書表
void SystemInitialize();
void SystemTerminate();
void SystemRun();
int main(int argc, char *argv[])
{
SystemInitialize();
SystemRun();
SystemTerminate();
system("PAUSE");
return 0;
}
void SystemInitialize ()
{
InitList ( s );
InitList ( b );
Book mybooks[] = {
{"C Programming Language"},
{"Data Structures"},
{"C++ Programming Language"},
{"Effactive C++"},
{"More Effactive C++"},
{"Design Patterns"}
};
for ( int i=0; i<6; i++ )
ListInsert( s, i, mybooks[i]);
}
void SystemRun()
{
char GetCommand();
void DoCommand (char cmd);
char cmd;
do {
cmd = GetCommand();
DoCommand(cmd);
} while ( cmd!='q' );
}
char GetCommand ()
{
char str[64];
printf("\na:新書 b:借書 r:還書 p:打印 q:退出\n" );
printf(".");
//cin.getline(str,64);
read(str);
return str[0];
}
void DoCommand ( char cmd )
{
void AddNewBook();
void BorrowBook();
void ReturnBook();
void PrintBookLists();
switch ( cmd ) {
case 'a':
AddNewBook();
break;
case 'b':
BorrowBook();
break;
case 'r':
ReturnBook();
break;
case 'p':
PrintBookLists();
break;
case 'q':
break;
default:
printf("命令錯誤");
}
}
void AddNewBook()
{
Book abook;
printf( "\n輸入新書名:");
ReadBook(abook);
if ( ListInsert(s,1,abook) )
printf( "入庫成功" );
else
printf( "入庫失敗" );
}
void BorrowBook()
{
Book abook;
int k;
printf("\n借書書名:");
ReadBook(abook);
k = LocateElem(s,abook,BookEqual);
if ( k!=0 ) {
// TODO (#1#): 借書,借書表加一,存書表減一
ListInsert(b, 1, abook );
ListDelete(s, 1, abook);
//-------------------------------------
printf("\n借書成功" );
} else
printf( "\n查無此書" );
}
void ReturnBook()
{
Book abook;
int k;
printf( "\n還書書名:");
ReadBook(abook);
k = LocateElem(b,abook,BookEqual);
if ( k!=0 ) {
// TODO (#1#): 還書,借書表減一,存書表加一
ListInsert(s, 1, abook );
ListDelete(b, 1, abook);
//-------------------------------------
printf("\n還書成功" );
} else
printf( "\n查無此書" );
}
void PrintBookLists()
{
printf( "庫存 %d本書\n" , ListLength(s) );
ListTraverse ( s, PrintBook );
printf( "\n借出%d本書 " , ListLength(b) );
ListTraverse ( b, PrintBook );
}
void SystemTerminate ()
{
DestroyList ( s );
DestroyList ( b );
}
主要的操作方法:
/*
Name: sqlist.h
Copyright:
Author:
Date: 21-03-05 20:21
Description:
*/
#ifndef SQLIST_H_INCLUDED
#define SQLIST_H_INCLUDED
#include "ds.h" //for Status,OK ...
#ifndef ElemType
#define ElemType int /* 數據元素類型默認爲 int */
#define ELEMTYPE_TAG
#endif
/**********************************************************
* 順序表的存儲結構定義
***********************************************************/
#define LIST_INIT_SIZE 100 /* 存儲空間初始分配容量 */
#define LISTINCREMENT 10 /* 存儲空間分配的增量 */
typedef struct {
ElemType *elem; //存儲空間基址
int length; //當前長度
int listsize; //當前已分配的存儲空間(元素個數)
} SqList;
/**********************************************************
* 順序表的基本操作聲明
***********************************************************/
//創建並初始化爲空表
Status InitList(SqList &L);
//銷燬整個表(從此之後不再可用)
Status DestroyList(SqList &L);
//將表L置空
Status ClearList(SqList &L);
//判斷表L是否爲空表
bool ListEmpty(SqList L);
//求表L的長度
int ListLength(SqList L);
//取表L中的第i個元素,並用e返回. 操作成功返回OK,失敗時返回ERROR
Status GetElem(SqList 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(SqList L, ElemType e,
bool (*compare)(ElemType,ElemType));
//在表L中插入第i個元素e. 操作成功返回OK,失敗時返回ERROR
Status ListInsert(SqList &L, int i, ElemType e);
//刪除表L中第i個元素,結果用e返回. 操作成功返回OK,失敗時返回ERROR
Status ListDelete(SqList &L, int i, ElemType &e);
//遍歷表L,對每個元素調用visit(x).
Status ListTraverse(SqList L, Status (*visit)(ElemType));
/**********************************************************
* 順序表的基本操作的實現
***********************************************************/
//創建並初始化爲空表
Status InitList(SqList &L)
{
// TODO (#1#): 創建空表
L.elem=(ElemType *)malloc(LIST_INIT_SIZE *sizeof(ElemType));
L.length=L.listsize=0;
return OK;
//-------------------------------------
}
//銷燬整個表(從此之後不再可用)
Status DestroyList(SqList &L)
{
// TODO (#1#): 銷燬表
if(L.elem){
free(L.elem);
return OK;
}
else{
return ERROR;
}
//-------------------------------------
}
//將表L置空
Status ClearList(SqList &L)
{
// TODO (#1#): 清空表
if(L.elem){
L.length = 0;
return OK;
}
else
return ERROR;
//-------------------------------------
}
//判斷表L是否爲空表
bool ListEmpty(SqList L)
{
// TODO (#1#): 順序表判空
if (L.length==0) return false;
else return OK;
//-------------------------------------
}
//求表L的長度
int ListLength(SqList L)
{
// TODO (#1#): 求順序表長度
return L.length;
return 0;
//-------------------------------------
}
//取表L中的第i個元素,並用e返回. 操作成功返回OK,失敗時返回ERROR
Status GetElem(SqList L, int i, ElemType &e)
{
// TODO (#1#): 取元素
if(i<1||i>L.length)
return ERROR;
e=L.elem[i-1];
return OK;
//-------------------------------------
}
//在表L中定位元素e首次出現的位置. 操作成功返回位序,失敗時返回0
// compare(a,b) 爲比較函數,匹配時返回true,否則返回false
int LocateElem(SqList L, ElemType e, bool (*compare)(ElemType,ElemType))
{
// TODO (#1#): 在表中定位元素e,用compare(a,b)匹配元素
for (int j=0; j<L.length; j++)
if ( compare(L.elem[j],e) ) return j+1;
return 0;
//-------------------------------------
}
//在表L中插入第i個元素e. 操作成功返回OK,失敗時返回ERROR
Status ListInsert(SqList &L, int i, ElemType e)
{
// TODO (#1#): 在鏈表中插入元素
if (i<1||i>L.length+1) return ERROR;
for(int j=L.length;j>=i;j--)
L.elem[j]=L.elem[j-1];
L.elem[i-1]=e;
L.length++;
return OK;
//-------------------------------------
}
//刪除表L中第i個元素,結果用e返回. 操作成功返回OK,失敗時返回ERROR
Status ListDelete(SqList &L, int i, ElemType &e)
{
// TODO (#1#): 在順序表中刪除元素
if(i<1||i>L.length)
return ERROR;
for(int j=i;j<=L.length;j++)
L.elem[j-1]=L.elem[j];
L.length--;
return OK;
//-------------------------------------
}
//遍歷表L,對每個元素調用visit(x).
Status ListTraverse(SqList L, Status (*visit)(ElemType))
{
// TODO (#1#): 遍歷順序表
for (int j=0; j<L.length; j++)
if ( ! visit(L.elem[j]) ) return ERROR;
return OK;
//-------------------------------------
}
#ifdef ELEMTYPE_TAG
#undef ElemType
#undef ELEMTYPE_TAG
#endif
#endif // SQLIST_H_INCLUDED
演示結果: