线性表的链式表示和实现
线性表的链式表示和实现
单链表的定义和表示
结点:数据域,指针域。
结点的储存结构:
typdef struct LNode{
ElemType data;//数据域
struct LNode *next;//指针域
}LNode,*Linklist;
LinkList和LNode * 等价,LinkList通常定义单链表头指针,LNode * 定义任意指针。
头指针:指向链表中第一个结点的指针。
首元结点:储存链表中第一个元素的结点。
头节点:首元结点之前的结点,头指针指向头节点,头节点的指针与指向首元结点的地址。
增加头节点的作用
- 便于首元结点的处理
- 便于空表和非空表的统一处理
单链表基本操作的实现
单链表实现图书管理系统
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define Status int
//图书结构定义
typedef struct Book {
string number;
string name;
float price;
}Book;
//单链表结构定义
typedef struct LNode {
Book data;
struct LNode* next;
}LNode,*LinkList;
//单链表初始化
Status InitList(LinkList& L) {
L = new LNode;
L->next = NULL;
return OK;
}
//单链表的创建
//前插法
Status CreateList_H(LinkList & L,int n) {
InitList(L);
LNode* p;
for (int i = 0; i < n; i++) {
p = new LNode;
cin >> p->data.number >> p->data.name >> p->data.price;
p->next = L->next;
L->next = p;
}
return OK;
}
//后插法
Status CreateList_R(LinkList& L, int n) {
InitList(L);
LNode* p;
LNode* r;
r = L;
for (int i = 0; i < n; i++) {
p = new LNode;
cin >> p->data.number >> p->data.name >> p->data.price;
p->next = NULL;
r->next = p;
r = p;
}
return OK;
}
//单链表的取值
Status GetElem(LinkList L, int i, Book& e) {
LNode* p; int j;
p = L->next; j = 1;
while (p && j < i) {
p = p->next;
j++;
}
if (!p || j > i)
return ERROR;
e = p->data;
}
//单链表的元素的修改
Status ModifyElem(LinkList& L, int i, Book e) {
LNode* p; int j;
p = L->next; j = 1;
while (p && j < i) {
p = p->next;
j++;
}
if (!p || j > i)
return ERROR;
p->data=e;
}
//单链表的查找
//按书名查找
LNode* LocatedElemName(LinkList L, Book e) {
LNode* p;
p = L->next;
while (p && p->data.name != e.name) {
p = p->next;
}
return p;
}
//按书号查找
LNode* LocatedElemNumber(LinkList L, Book e) {
LNode* p;
p = L->next;
while (p && p->data.number != e.number) {
p = p->next;
}
return p;
}
//按价格查找
LNode* LocatedElemPrice(LinkList L, Book e) {
LNode* p;
p = L->next;
while (p && p->data.price != e.price) {
p = p->next;
}
return p;
}
//单链表的插入
Status ListInsert(LinkList& L, int i, Book e) {
LNode* p;
p = L; int j = 0;
while (p && (j < i - 1)) {
p = p->next; j++;
}
if (!p || j > i - 1) return ERROR;
LNode* s;
s = new LNode;
s->data.name = e.name;
s->data.number = e.number;
s->data.price = e.price;
s->next = p->next;
p->next = s;
return OK;
}
//单链表的删除
Status ListDelete(LinkList& L, int i) {
LNode* p;
p = L; int j = 0;
while ((p->next) && (j < i - 1)) {
{
p = p->next;
j++;
}
}
if(!(p->next)||(j>i-1)) return ERROR;
LNode* q;
q = p -> next;
p->next = q->next;
delete q;
return OK;
}
//单链表的输出
void ShowList(LinkList L) {
LNode* p;
p = L->next;
while (p) {
cout << p->data.name<<" " << p->data.number << " " << p->data.price<<endl;
p = p->next;
}
}
int main()
{
int a = 1; int b = 0; int i;
LinkList l; InitList(l);
while (a==1) {
cout << " 图书管理系统 " << endl;
cout << " 1 输入图书信息并储存 2 删除图书 3 插入图书 " << endl;
cout << " 4 查找图书 5 修改图书 6 查看图书列表 " << endl;
cin >> b;
switch (b)
{
case 1: {
cout << "请输入存入图书的本数" << endl;
cin >> i;
cout << "请依次输入图书的书号,书名及价格" << endl;
CreateList_R(l, i);
break; }
case 2: {
cout << "请输入删除图书的位置" << endl;
cin >> i;
ListDelete(l, i);
break; }
case 3: {
Book book1;
cout << "请输入插入图书的信息" << endl;
cin >> book1.number >> book1.name >> book1.price;
cout << "请输入插入图书的位置" << endl;
cin >> i;
ListInsert(l, i, book1);
break; }
case 4: {
Book book2;
cout << "请输入查找图书的信息" << endl;
cout << "请依次输入书号,书名,价格" << endl;
cin >> book2.number >> book2.name >> book2.price;
cout << "请选择查找方式 " << endl;
cout<<"1 书名查找 2 书号查找 3 价格查找" << endl;
cin >> i;
if (i == 1) {
if (LocatedElemNumber(l, book2))
cout << "查找成功" << endl;
else
cout << "查找失败" << endl;
}
else if(i==2) {
if (LocatedElemNumber(l, book2))
cout << "查找成功" << endl;
else
cout << "查找失败" << endl;
}
else{
if (LocatedElemNumber(l, book2))
cout << "查找成功" << endl;
else
cout << "查找失败" << endl;
}
break;
}
case 5: {
Book book3;
cout << "请输入修改图书的位置" << endl;
cin >> i;
cout << "请输入将要修改的信息" << endl;
cout << "请依次输入书号,书名,价格" << endl;
cin >> book3.number >> book3.name >> book3.price;
ModifyElem(l, i, book3);
break; }
case 6: {
ShowList(l);
break; }
}
cout << "是否继续,继续请输入1" << endl;
cin >> a;
}
}
循环链表
表中最后一个指针域指向头节点
与单链表差别:
判别条件不同
单链表 | 循环链表 |
---|---|
p!=NULL | p!=L |
p->next!=NULL | p->next!=L |
双向链表
两个指针域,一个指向直接后继,一个指向直接前驱。
typedef struct DuLNode{
ElemType data;
struct DuLNode *prior;
struct DulNode *next;
}DuLNode,*DulinkList
双向链表的插入
Status ListInsert_DuL(DuLinkList &L,int i,ElemType e){
if(!(p=GetElem_DuL(L,i)))
return ERROR;
s = new DuLNode;
s->data = e;
s->prior = p->prior;
p->prior->next = s;
s->next = p;
p->prior = s;
return OK;
}
双向链表的删除
Status ListDelete_DuL(DuLinkList &L,int i){
if(!p=GetElem_Dul(L,i))
return ERROR;
p->prior->next = p->next;
p->next->prior = p->prior;
delete p;
return OK;
}