求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++链式链表的程序的主要内容,如果未能解决你的问题,请参考以下文章