数据结构--线性表(单链表)

正在学习数据结构,第一步是线性表,写一个bookLinkList.

同时开始用vianal studio. 当然不是很熟悉这个IDE,但感觉挺厉害的。

下面的这个booklist 不是本人写的,感谢Liu老师。

 

链表是一种动态结构,整个可用存储空间可为多个链表共同享用。

每个链表占用的空间不需要预先分配划定,而是系统按需及时生成。

建立线性表的链式存储结构的过程是一个动态生成链表的过程。

从空表的初始状态起,依次建立各元素节点,并逐个插入链表。


// BookLinkList.cpp : This file contains the 'main' function. Program execution begins and ends there.
// by lyj.


#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;

typedef struct Book
{
    char no[20];
    char name[50];
    float price;
  //符号重载
bool operator==(const Book& anotherbook) { return (!strcmp(no, anotherbook.no)); } bool operator!=(const Book& anotherbook) { return(strcmp(no, anotherbook.no)); } friend istream &operator >> (istream &i, Book& b)//输入流 { cout << "请输入书号:"; i >> b.no; cout << "请输入书名:"; i >> b.name; cout << "请输入价格:"; i >> b.price; cout << " "; return i; } }Book; typedef struct LNode//(1)LNode是结构类型名 { Book data; struct LNode *next;//(2)第二个LNode是用的(1)定义了一个LNode类型的指针 }LNode, *LinkList;//(3)第三个LNode是(1)结构体的别名,这里用了相同的名字。LinkList=LNode *; //一般用LinkList定义单链表头指针,用LNode*定义某个节点指针

*** 注意区分头结点,首元结点,头指针。

    初始化链表(只有一个头节点的空链表)

Status InitList(LinkList &L)
{
    L = new LNode;
    L->next = NULL;
    return OK;
}

——下面的函数是假定链表已经存在多个节点:


1、取值   用指针p指向首元结点,用 j 做计数器初值赋1 。从首元结点开始依次顺着链域next向下访问,只要指向当前节点的指针p不为NULL,并没有达到序号为 i 的节点,则循环操作:p指向下一个节点,计时器 j 相应加1 。取值算法的时间复杂度为:O(n)

tatus 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;
    return OK;
}

 2、查找 从链表的首元结点出发,依次将节点值和给定值e进行比较,返回查找结果。查找算法时间复杂度也为:O(n)

LNode *LocateElem(LinkList L, Book e)
{
    LNode *p;
    p = L->next;
    while (p && p->data != e)
        p = p->next;
    return p;
}

 3、插入 (可插入位置为n+1个)时间复杂度也为:O(n)

Status ListInsert(LinkList &L, int i, Book e)
{
    LNode *s, *p; int j;
    p = L; j = 0;
    while (p && j < i - 1) { p = p->next; j++; }//查找第i-1个节点,p指向该节点
    if (!p || j > i - 1) return ERROR;
    s = new LNode;
    s->data = e;//将e存入*s的数据域
    s->next = p->next;//把p的下一个节点的地址给*s的指针域,即将p后面的节点连入s的尾部
    p->next = s;//将s本身的地址(理解为s的头)放入p的尾部
    return OK;
}

 删除节点(按序号删除 和 按节点中数据项关键字删除)

Status ListDelete(LinkList &L, int i)   //按序号删除元素(结点)
{
    LNode *p, *q; int j;
    p = L; j = 0;
    while (p->next && j < i - 1) { p = p->next; j++; }
    if (!p->next || j > i - 1) return ERROR;
    q = p->next;
    p->next = q->next;
    delete q;
    return OK;
}
Status DelElem(LinkList &L, Book e)  //按结点中数据项的关键字值删除结点
{
    LNode *p, *q;
    p = L;
    while (p->next && strcmp(p->next->data.no, e.no))
    {
        p = p->next;
    }
    if (!p->next) return ERROR;
    q = p->next;
    p->next = q->next;
    delete q;
    return OK;
}

4、链表销毁

Status DestroyList(LinkList &L)
{
    LNode *p;
    while (L->next != NULL)
    {
        p = L;
        L = L->next;
        delete p;
    }
    delete L;
    return OK;
}

5、链表显示

void ListDisplay(LinkList L)
{
    cout << "书号	书名	价格
";
    while (L->next != NULL)
    {
        L = L->next;
        cout << L->data.no << "	" << L->data.name << "	" << L->data.price << "
";
    }
}

前面只创建了有一个头结点的空链表,下面将建立一个包含若干个节点的链表

根据节点插入位置不同,链表的创建可以分为:前插 和 后插

void CreateList_H(LinkList &L, int n)  //前插法
{
    LNode *p;
    L = new LNode;
    L->next = NULL;
    for (int i = 0; i < n; i++)
    {
        p = new LNode;
        cin >> p->data;
        p->next = L->next;
        L->next = p;
    }
}
void CreateList_R(LinkList &L, int n)  //后插法
{
    LNode *r, *p;
    L = new LNode;
    L->next = NULL;
    r = L;
    for (int i = 0; i < n; i++)
    {
        p = new LNode;
        cin >> p->data;
        p->next = NULL;
        r->next = p;
        r = p;
    }
}

差不多就是这样,然后来一个main测试一下

int main()
{
    LinkList bookLinkList;
    char ch; int n;
    cout << "
+-------------------------------------------------------+
";
    cout << "+ 请选择要进行的操作:					+
";
    cout << "+	<按数字键1> 创建一个只含头结点的空的单链表	+
";
    cout << "+	<按数字键2> 创建一个包含头结点和n个元素的单链表	+
";
    cout << "+	<按其他任意键> 退出程序				+
";
    cout << "+-------------------------------------------------------+
";
    ch = _getwch();
    if (ch == '1')
    {
        InitList(bookLinkList);
    }
    else if (ch == '2')
    {
        cout << "
请输入单链表中要包含的元素个数:";
        cin >> n;
        cout << "请选择:<a>使用前插法	<b>使用后插法
";
        while (1)
        {
            ch = _getwch();
            if (ch == 'a')
            {
                CreateList_H(bookLinkList, n);
                break;
            }
            else if (ch == 'b')
            {
                CreateList_R(bookLinkList, n);
                break;
            }
        }
    }
    else
    {
        exit(0);
    }
    while (1)
    {
        cout << "

------------------------------------------------------------------------------------
";
        cout << "+请选择要进行的操作:<a>显示    <b>插入元素    <c>删除元素    <d>查找    <x>退出+
";
        cout << "------------------------------------------------------------------------------------
";
        ch = _getwch();
        if (ch == 'x')
            break;
        else if (ch == 'a')
            ListDisplay(bookLinkList);
        else if (ch == 'b')
        {
            int i;
            cout << "请输入插入的位置:";
            cin >> i;
            Book b;
            cin >> b;
            if (ListInsert(bookLinkList, i, b) == OK)
                cout << "元素插入第" << i << "个位置成功。
";
            else
                cout << "元素插入第" << i << "个位置失败。
";
        }
        else if (ch == 'c')
        {
            cout << "请选择:<a>按位置序号删除元素	<b>按元素中数据项的关键字值删除元素
";
            while (1)
            {
                ch = _getwch();
                if (ch == 'a')
                {
                    cout << "请输入要删除的元素的位置序号:";
                    int i;
                    cin >> i;
                    if (ListDelete(bookLinkList, i) == OK)
                        cout << "删除成功!
";
                    else
                        cout << "删除失败!
";
                    break;
                }
                else if (ch == 'b')
                {
                    cout << "请输入要删除的书籍的书号:";
                    Book b;
                    cin >> b.no;
                    if (DelElem(bookLinkList, b) == OK)
                        cout << "删除成功!
";
                    else
                        cout << "删除失败!
";
                    break;
                }
            }
        }
        else if (ch == 'd')
        {
            cout << "请输入要查找的书籍的书号:";
            Book t;
            cin >> t.no;
            LNode *p = LocateElem(bookLinkList, t);
            if (p == NULL)
                cout << "查找失败!
";
            else
            {
                cout << "查找成功! 找到的书籍为:
";
                cout << "书号	书名	价格
";
                cout << p->data.no << "	" << p->data.name << "	" << p->data.price << "
";
            }
        }

    }

    DestroyList(bookLinkList);
}
原文地址:https://www.cnblogs.com/cjwen/p/10501570.html