线性表的链式表示和实现

单链表的定义和表示

结点:数据域,指针域。
结点的储存结构:

typdef struct LNode{
	ElemType data;//数据域
	struct LNode *next;//指针域
}LNode,*Linklist;

LinkList和LNode * 等价,LinkList通常定义单链表头指针,LNode * 定义任意指针。

头指针:指向链表中第一个结点的指针。
首元结点:储存链表中第一个元素的结点。
头节点:首元结点之前的结点,头指针指向头节点,头节点的指针与指向首元结点的地址。

增加头节点的作用

  1. 便于首元结点的处理
  2. 便于空表和非空表的统一处理

单链表基本操作的实现

单链表实现图书管理系统

#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;
}

链表之间的比较

线性表的链式表示和实现_数据

顺序表与链表比较

线性表的链式表示和实现_链表_02