求1个C++链式链表的程序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求1个C++链式链表的程序相关的知识,希望对你有一定的参考价值。

初学者,结构越看得懂越好

List是一个比较简单的单向链表类,拥有插入删除等基本功能。
Node是结点类,只在List中用到。
我加了比较详细的注释,相信你能看的懂:)

#include <iostream>

//结点类
class Node

//申明List为友元
friend class List;

private:
//构造函数设为私有,只有友元可以调用
Node(int data = 0, Node* pNext = NULL) : m_data(data), m_pNext(pNext)



private:
int m_data; //数据
Node* m_pNext; //下一个结点的指针
;

class List

public:
//构造函数
List() : m_nCount(0), m_pHead(NULL)



//构造函数,初始化时就创建一个链表
//nCount 链表结点数
//InitData 初始数据
//Step 步长,每个结点的值会递增这个步长
List(int nCount, int InitData = 0, int Step = 0) : m_nCount(0), m_pHead(NULL)

for (int i = 0; i < nCount; i++)

Insert(i, InitData);
InitData += Step;



//析构函数,析构时删除链表各结点,回收空间
~List()

DeleteAll();


//复制构造函数
List(const List& list) : m_nCount(0), m_pHead(NULL)

//使用=号操作符函数
operator=(list);


//重载=号操作
List& operator=(const List &list)

//如果是本身则直接返回
if (&list == this)

return *this;


//先删除所有结点
DeleteAll();

//重新分配空间并赋值
if ( !list.IsEmpty() )

m_pHead = new Node(list.m_pHead->m_data, list.m_pHead->m_pNext);
m_nCount = list.m_nCount;

Node *pSrcNode = list.m_pHead->m_pNext;
Node *pDestNode = m_pHead;
while (pSrcNode != NULL)

pDestNode->m_pNext = new Node(pSrcNode->m_data);

pDestNode = pDestNode->m_pNext;
pSrcNode = pSrcNode->m_pNext;



return *this;


//是否为空,以结点数是否为0来判断
bool IsEmpty() const

return (m_nCount == 0);


//得到结点的数量
int GetCount() const

return m_nCount;


//插入操作
//index 要插入的位置,从0开始算起
//data 插入结点的值
//成功返回插入的位置,失败则返回-1
int Insert(int index, int data)

//计算正确的index
index = index >= 0 ? index : 0;
index = index > m_nCount ? m_nCount : index;

Node *pAdd = new Node(data);

//如果是插入到链表头
if (index == 0)

/*
* head
* |
* newnode node(0)->node(1)->...
*
* head
* |
* newnode->node0->node1->...
*
* head
* |
* newnode->node0->node1->...
*/
pAdd->m_pNext = m_pHead;
m_pHead = pAdd;

//如果是插入到链表的其他位置
else

/*
* newnode->NULL
*
* ...->node(i)->node(i+1)->...
*
* newnode
* \
* ...->node(i)->node(i+1)->...
*
* newnode
* / \
* ...->node(i) node(i+1)->...
*/
Node *pNode = m_pHead;
for (int i = 0; i < index - 1; i++)

pNode = pNode->m_pNext;


pAdd->m_pNext = pNode->m_pNext;
pNode->m_pNext = pAdd;


m_nCount++;

return index;


//删除操作
//index 要删除的位置,从0开始算起
//成功返回删除的位置,失败则返回-1
int Delete(int index)

//为空不能进行删除操作
if ( IsEmpty() )

return -1;


//计算正确的index
index = index >= 0 ? index : 0;
index = index >= m_nCount ? m_nCount - 1 : index;
Node *pDelete = m_pHead;

if (index == 0)

/*
* head
* |
* node(0)->node(1)->...
*
* head
* |
* node(0)->node(1)->...
*
* head
* |
* node(1)->...
*/
m_pHead = m_pHead->m_pNext;

else

/*
* node(i)
* / \
* ...->node(i-1) node(i+1)->...
*
* node(i)
* \
* ...->node(i-1)->node(i+1)->...
*
*
* ...->node(i-1)->node(i+1)->...
*/
for (int i = 0; i < index - 1; i++)

pDelete = pDelete->m_pNext;


Node *pTemp = pDelete;
pDelete = pDelete->m_pNext;
pTemp->m_pNext = pTemp->m_pNext->m_pNext;


delete pDelete;
m_nCount--;

return index;


//全部删除
void DeleteAll()

while (m_pHead != NULL)

Node *pTemp = m_pHead;
m_pHead = m_pHead->m_pNext;
delete pTemp;

m_nCount = 0;


//打印链表
void Print() const

Node *pNode = m_pHead;
while (pNode != NULL)

std::cout<<"["<<pNode->m_data<<"]->";
pNode = pNode->m_pNext;

std::cout<<"NULL"<<std::endl;


private:
int m_nCount;
Node* m_pHead;
;

int main()

List list1(10, 0, 2);
List list2(list1);
list1.Delete(3);
list1.Print();

list2.Print();

List list3;
list3 = list2;
list3.Insert(0, -1);

list3.Print();

return 0;
参考技术A 现写的,因为你说自己是初学,也不知道你懂不懂模板所以我没用,数据结构用的是比较简单的单链表,懂了这个以后,双链表和其他类型的链表也就很容易理解了,代码安排有点乱,声明和定义都放一块了:

#include <iostream>
#include <cstddef>

class slist 
    struct Node // 节点结构
    
        int data;
        Node* next;
    ;
    
public:
    class iterator  // 跌代器
        friend class slist;
    public:
        iterator() : node(0) 
        iterator(const iterator& rhs) : node(rhs.node) 
        iterator& operator = (const iterator& rhs) node = rhs.node; return *this;
    
        int& operator * () const return node->data;
        Node* operator -> () const return node;
        bool operator == (const iterator& rhs) const return node == rhs.node;
        bool operator != (const iterator& rhs) const return node != rhs.node;
        bool null() const return node == 0;
        iterator& operator ++ () node = node->next; return *this;
        iterator operator ++ (int) iterator temp(*this); ++*this; return temp;
        
        private:
            iterator(Node* theNode) : node(theNode)  // 用于slist类
            Node* node;
    ;

    slist() : head(0), tail(&head), numElems(0)  // 默认构造
    
    slist(const int* beg, const int* end) // 从数组初始化
    : head(0), tail(&head), numElems(0) 
    
        while(beg != end)
            push_back(*beg++);
    
    
    slist(const slist& rhs) // cc
    : head(0), tail(&head), numElems(0)
    
        assign(*this, rhs);
    
    
    slist& operator = (const slist& rhs) // operator =
    
        assign(*this, rhs);
        return *this;
    
    
    void push_back(int elem) // 向后插入元素
    
        *tail = new Node;
        (*tail)->data = elem;
        (*tail)->next = 0;
        tail = &(*tail)->next;
        ++numElems;
    
    
    void push_front(int elem) // 向前插入元素
    
        Node* node = new Node;
        node->data = elem;
        node->next = head;
        head = node;
        ++numElems;
    
    
    iterator begin() const return iterator(head); // 表首
    iterator end() const return iterator(*tail); // 表尾
    
    void insert(iterator it, int elem) // 在指定位置插入元素
    
        Node* node = new Node;
        node->data = *it;
        node->next = it.node->next;
        *it = elem;
        it.node->next = node;
        ++numElems;
    
    
    void remove(iterator it) // 移除指定位置的元素
    
        Node* nodeToRemove = it.node;
        
        if(nodeToRemove == head)
            head = head->next;
        else if(&nodeToRemove->next == tail)
            *(tail = &(getPrevNode(nodeToRemove)->next)) = 0;
        else
            getPrevNode(nodeToRemove)->next = nodeToRemove->next;
        
        delete nodeToRemove;
        --numElems;
    
    
    iterator search(int elem) // 查找某元素是否在链表内
    
        Node* node = head;
        while(node && node->data != elem)
            node = node->next;
        return iterator(node);
    
    
    std::size_t size() const return numElems; // 元素个数
    bool empty() const return numElems == 0; // 空表?
    
    friend std::ostream& operator << (std::ostream& os, const slist& sl) // 重载输出
    
        Node* node = sl.head;
        while(node)
        
            os << node->data << ' ';
            node = node->next;
        
        return os << '\n';
    
    
    void sort() // 排序
    
        _imp_quickSort(head, *tail);
    
    
    void clear() // 清空表
    
        Node* node;
        while(head)
        
            node = head;
            head = head->next;
            delete node;
        
        head = 0;
        tail = &head;
        numElems = 0;
    
    
    ~slist()clear(); // 析构
private:
    Node* getPrevNode(Node* node) const // 内部函数,获得某节点的前一个节点
    
        Node* temp = head;
        Node* prev;
        while(temp != node)
        
            prev = temp;
            temp = temp->next;
        
        return prev;
    

    static void assign(slist& lhs, const slist& rhs) // 内部函数,赋值
    
        lhs.clear();
        Node* node = rhs.head;
        while(node)
        
            lhs.push_back(node->data);
            node = node->next;
        
    
    
    static void _imp_swap(int& lhs, int& rhs) // 内部函数,交换
    
        int temp = lhs;
        lhs = rhs;
        rhs =temp;
    

    static void _imp_quickSort(Node* head, Node* tail) // 内部函数,排序
    
        if(head != tail)
        
            Node* pivot = head;
            while(pivot->next != tail)
                pivot = pivot->next;

            Node* beg = head;
            Node* exc = head;

            while(beg != pivot)
            
                if(beg->data < pivot->data)
                
                    _imp_swap(beg->data, exc->data);
                    exc = exc->next;
                
                beg = beg->next;
            
            _imp_swap(exc->data, pivot->data);
            _imp_quickSort(head, exc);
            _imp_quickSort(exc->next, tail);
        
    
    
    Node* head;
    Node** tail;
    std::size_t numElems;
;

inline void PrintMsg(const char* msg, const slist& sl) // 示范用函数

    std::cout << msg << sl << '\n';


int main()

    int a[] = 9,0,7,5,3,2,8,4,6,1;
    slist s(a, a + 10);
    
    PrintMsg("s: ", s);
    
    s.sort();
    PrintMsg("after sort: ", s);
    
    s.insert(++s.begin(), 11);
    PrintMsg("insert elem 11 at pos 2: ", s);
    
    s.remove(s.search(4));
    PrintMsg("delete elem 4: ", s);
    
    s.sort();
    PrintMsg("s: ", s);
    std::cout.setf(std::ios::boolalpha);
    std::cout << "s contains 4: " << !s.search(4).null() << '\n';
    std::cout << "s contains 6: " << !s.search(6).null() << "\n\n";
    
    s.push_front(-6);
    s.push_back(19);
    PrintMsg("insert -6 & 19 at the front and end respectively:\n", s);
    
    std::cout << "there are " << s.size() << " elems in the list.\n\n";
    
    std::cout << "use iterator to iterate through the list:\n";
    for(slist::iterator it = s.begin(); it != s.end(); ++it)
        std::cout << *it << '*';
    
    s.clear();
    std::cout << "\n\nclean up list s, is s now empty? " << s.empty() << "\n\n";
参考技术B #include<iostream>
#include<string>
using namespace std;
class infoOrder


public:
char PID[5];
int amount;
void get(char p[],int n)

/*cout<<"Enter the PID"<<endl;
memset(PID,0,5);
cin>>PID;
cout<<"Enter the amount"<<endl;
cin>>amount;
cin.ignore();*/
memset(PID,0,5);
strcpy(PID,p);//产品代码
amount=n;//订购数量


void display()//显示单个产品条目的信息

cout<<"产品代码:"<<PID<<","<<"产品数量:"<<amount<<endl;


;

class Node

public:
//infoOrder *info;
infoOrder info;//直接定义实体就可以了,没必要用指针。
Node *NEXT; //链表接点指针
Node (char *p,int n)/*infoOrder *s=NULL,Node *n=NULL*//*:info(s),NEXT(n) */

info.get(p,n);
;
;
class List

private:
Node *START;
/* *CURRENT,
*PRECEDE; */
public:
List()

START=NULL;/*=CURRENT=PRECEDE=*/
;
~List()

destroy();

void addNode(infoOrder *s); //增加购买条目
bool delNode(infoOrder *s); //删除某个购买条目
bool updateNode(infoOrder *s);//更新某个购买条目的数量
void traverse(); //显示购买清单
void destroy(); //销毁购买清单
;

void List::destroy()

/*while(START!=NULL)

CURRENT=START;
START=START->NEXT;
delete CURRENT;
*/
//START=PRECEDE=CURRENT=NULL;
START=NULL;


void List::addNode(infoOrder *s)

/*if(START==NULL||s<=START->info) //为什么START=NULL就是节点为空?最后一个节点指针也是空啊?

START=new Node(s,START);
return;

Node *prev,*curr;
for(prev=curr=START;curr!=NULL&&s>curr->info;prev=curr,curr=curr->NEXT);
Node *n=new Node(s,curr);
prev->NEXT=n;*/
if(START==NULL)//链表为空时

START=new Node(s->PID,s->amount);
START->NEXT=NULL;

else//链表为非空时,插到表头

Node *p=new Node(s->PID,s->amount);
p->NEXT=START;
START=p;




bool List::updateNode(infoOrder *s)

/*for (PRECEDE=CURRENT=START;CURRENT&&s!=CURRENT->info;PRECEDE=CURRENT,CURRENT=CURRENT->NEXT);

return(CURRENT!=NULL);*/
Node *p=START;
for(p;p!=NULL;p=p->NEXT)//循环查找匹配的产品

if(strcmp(p->info.PID,s->PID)==0)//找到要修改的接点。

p->info.get(s->PID,s->amount);


return true;

void List::traverse()

Node *p=START;
if(START!=NULL)

cout<<"产品清单为:"<<endl;
for(p;p!=NULL;p=p->NEXT)//循环显示每一个产品

//p->info.display;
cout<<"商品代码"<<p->info.PID<<","<<"商品数量"<<p->info.amount<<endl;


else

cout<<"清单为空"<<endl;




bool List::delNode(infoOrder *s)


int flag=0;
/*if(queryNode(s)==false)

return false;

PRECEDE->NEXT=CURRENT->NEXT;
if(CURRENT==START)

START=START->NEXT;

delete CURRENT;*/
if(START==NULL)

cout<<"清单为空,删除操作失败"<<endl;

else

Node *p=START;
Node *p1=START;
for(p;p!=NULL;p=p->NEXT)//循环查找匹配的产品

if(strcmp(p->info.PID,s->PID)==0)

flag=1;
break;


if(p==START)//删除头结点

START=START->NEXT;
p->NEXT==NULL;
delete p;

else if(p!=NULL)

for(p1=START;p1->NEXT!=p;p1=p1->NEXT);//删除非头结点,找到p的前一个接点。作好删除准备
p1->NEXT=p->NEXT;
p->NEXT=NULL;
delete p;



if(flag==0)

cout<<"清单中没有要删除的商品"<<endl;


return true;

int main()

infoOrder *sh;
sh=new infoOrder;
List obj;
char name[5];
int num;
int flag=1;
while(flag)

cout<<"1.Enter name:"<<endl;
cout<<"2.Delete name:"<<endl;
cout<<"3.Update node:"<<endl;
cout<<"4.Display name:"<<endl;
cout<<"5.Destroy the list:"<<endl;
char ch;
cin>>ch;
switch(ch)

case '1'://添加结点

cout<<"输入要填加的商品和采购数量"<<endl;
cin>>name;
cin>>num;
sh->get(name,num);
obj.addNode(sh);

break;
case '2'://删除结点

cout<<"输入要删除的商品和采购数量"<<endl;
cin>>name;
cin>>num;
sh->get(name,num);
if(obj.delNode(sh)==false)

cout<<"not found"<<endl;


break;
case '3'://修改结点

cout<<"输入要修改的商品和采购数量"<<endl;
cin>>name;
cin>>num;
sh->get(name,num);
/*if(obj.queryNode(sh)==false)

cout<<"not found"<<endl;

else

cout<<"found in list"<<endl;
*/
obj.updateNode(sh);

break;
case '4'://遍历结点
obj.traverse();
break;
case '5'://清空清单
obj.destroy();
break;

cout<<"继续操作请输入1,退出请输入0"<<endl;
cin>>flag;

delete sh;
return 0;

4-3 求链式表的表长 (10分)

本题要求实现一个函数,求链式表的表长。

函数接口定义:

int Length( List L );

其中List结构定义如下:

typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode List;

L是给定单链表,函数Length要返回链式表的长度。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode List;

List Read(); /* 细节在此不表 */

int Length( List L );

int main()
{
    List L = Read();
    printf("%d\n", Length(L));
    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

1 3 4 5 2 -1

输出样例:

5

代码展示:
 1 List Read()
 2 {
 3     PtrToLNode head = NULL;
 4     PtrToLNode list = NULL;
 5     int data;
 6     scanf("%d",&data);
 7     if(data!=-1)
 8     {
 9         head = (PtrToLNode)malloc(sizeof(struct LNode));
10         head->Data = data;
11         head->Next = NULL;
12         list=head;
13     }
14     scanf("%d",&data);
15     while(data!=-1)
16     {
17         PtrToLNode node = NULL;
18         node = (PtrToLNode)malloc(sizeof(struct LNode));
19         node->Data = data;
20         node->Next = NULL;
21         list->Next = node;
22         list = node;
23         scanf("%d",&data);
24     }
25     return head;
26 }
27 int Length( List L )
28 {
29     int len= 0;
30     while(L)
31     {
32         len++;
33         L = L->Next;
34     }
35     return len;
36 }

 

以上是关于求1个C++链式链表的程序的主要内容,如果未能解决你的问题,请参考以下文章

下列函数试图求链式存储的线性表的表长,为啥是错的?

双向链式线性表(模板实现)

线性表的链式存储结构

线性表的链式存储结构 ( 链表 )

6-3 求链式表的表长

C语言基础知识中:线性表的顺序、链式存储结构分别是:随机存取和顺序存取结构对吗?