zoukankan      html  css  js  c++  java
  • 数据结构--线性表(单链表)

    正在学习数据结构,第一步是线性表,写一个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);
    }
  • 相关阅读:
    WCF 第八章 安全 确定替代身份(中)使用AzMan认证
    WCF 第八章 安全 总结
    WCF 第八章 安全 因特网上的安全服务(下) 其他认证模式
    WCF Membership Provider
    WCF 第八章 安全 确定替代身份(下)模仿用户
    WCF 第八章 安全 因特网上的安全服务(上)
    WCF 第九章 诊断
    HTTPS的七个误解(转载)
    WCF 第八章 安全 日志和审计
    基于比较的排序算法集
  • 原文地址:https://www.cnblogs.com/cjwen/p/10501570.html
Copyright © 2011-2022 走看看