線性表的鏈式表示和實現
單鏈表的定義和表示
結點:數據域,指針域。
結點的儲存結構:
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;
}