线性表(2)--链表模拟
线性表--链表的类实现:
简要介绍:
物理存储单元非连续、非顺序的存储结构,逻辑结构,由一系列的节点组成
节点:由指针域和数据域组成
分类:单向链表、静态链表、双向链表、循环链表
优点:
插入与删除快,大小可变不用去确定
缺点:
与顺序表相比操作复杂,查找较差,找数必需从头开始找
//------------------------------------------------------
//-------------链表的模拟实现:---------------------
Node.h
Node.cpp
List.h
List.cpp
demo.cpp
//控制台运行结果:
遍历:
3
6
2
4
2 的前驱为:6
2 的后继为:4
删除的第一个节点:3
删除后遍历:
6
2
4
线性表--链表的类实现:
简要介绍:
物理存储单元非连续、非顺序的存储结构,逻辑结构,由一系列的节点组成
节点:由指针域和数据域组成
分类:单向链表、静态链表、双向链表、循环链表
优点:
插入与删除快,大小可变不用去确定
缺点:
与顺序表相比操作复杂,查找较差,找数必需从头开始找
//------------------------------------------------------
//-------------链表的模拟实现:---------------------
Node.h
#ifndef NODE_H
#define NODE_H
class Node{
public:
int data;//int数据域, 这里可以为任意类型数据域,如Coordinate类、double.....
Node *next;//指针域
void printNode() const;
};
#endif
Node.cpp
#include"Node.h"
#include<iostream>
using namespace std;
void Node::printNode() const{
cout << data << endl;
}
List.h
#ifndef LIST_H
#define LIST_H
//-------------------
#include"Node.h"
//template <typename T>
class List{
public:
List();//创建线性表
~List();//销毁线性表
void clearList();//清除
bool listEmpty();//判空
int listLength() const;//线性表长度
bool getElement(int i, Node *pNode);//获取指定元素
int locElement(Node *pNode);//寻找第一个满足e数据元素的位序
bool priorElement(Node *pCurrentNode, Node *preElem);//获得前驱
bool nextElement(Node *pCurrentNode, Node *nextElem);//获得后驱
void listTraverse();//遍历
bool listInsert(int i, Node *pNode);//在i位置插入元素e
bool listDelete(int i, Node *pNode);//删除第i个位置
bool listInsertHead(Node *pNode);//在第一个节点前插入一个节点
bool listInsertTail(Node *pNode);//在末尾插入节点
private:
Node *m_pList;
int m_iLength;
};
#endif LIST_H
List.cpp
#include"List.h"
#include<iostream>
using namespace std;
//----------------------
List::List(){//初始化
m_pList = new Node;//这个申请的节点并不算在当前链表之中(1)
//m_pList->data = 0;//数据域
m_pList->next = NULL;//指针域
m_iLength = 0;
}
List::~List(){
clearList();//清空链表
delete m_pList;//释放(1)中节点
m_pList = NULL;
}
void List::clearList(){
Node *currentNode = m_pList->next;
while(currentNode != NULL){
Node * t = currentNode->next;
delete currentNode;
currentNode = t;
}
m_pList->next = NULL;
m_iLength = 0;
}
bool List::listEmpty(){
return 0 == m_iLength ? true : false;
}
int List::listLength() const{
return m_iLength;
}
bool List::getElement(int i, Node *pNode){
if(i < 0 || i >= m_iLength){
return false;
}
Node *currentNode = m_pList;
Node *currentNodeBefore = NULL;
for(int j = 0; j <= i; j++){//多循环了一次,即删除的节点为currentNode!
currentNodeBefore = currentNode;
currentNode = currentNode->next;
}
pNode->data = currentNode->data;
return true;
}
int List::locElement(Node *pNode){
Node *currentNode = m_pList;
int count = 0;
while(currentNode != NULL){
//头节点head的第一个数据域没有意义,0号节点应该是我们要找的第一个节点,即head的后一个节点
currentNode = currentNode->next;
if(currentNode->data == pNode->data){
return count;
}
count++;
}
return -1;
}
bool List::priorElement(Node *pCurrentNode, Node *preElem){
Node *currentNode = m_pList;
Node *currentNodeBefore = NULL;
while(currentNode->next != NULL){
//头节点head的第一个数据域没有意义,0号节点应该是我们要找的第一个节点,即head的后一个节点
currentNodeBefore = currentNode;
currentNode = currentNode->next;
if(currentNode->data == pCurrentNode->data){
if(currentNodeBefore == m_pList){//head节点后的第一个节点,我们也是认为没有前驱的
cout << "没有前驱" << endl;
return false;
}
preElem->data = currentNodeBefore->data;
return true;
}
}
return false;
}
bool List::nextElement(Node *pCurrentNode, Node *nextElem){
Node *currentNode = m_pList;
while(currentNode->next != NULL){
currentNode = currentNode->next;
if(currentNode->data == pCurrentNode->data){
nextElem->data = currentNode->next->data;
return true;
}
}
cout << "没有后继" << endl;
return false;
}
void List::listTraverse(){
Node *currentNode = m_pList;
while(currentNode->next != NULL){
currentNode = currentNode->next;
currentNode->printNode();//head后面的才算第一个节点
}
}
bool List::listInsert(int i, Node *pNode){
if(i < 0 || i > m_iLength){
return false;
}
Node *currentNode = m_pList;
for(int j = 0; j < i ; j++){
currentNode = currentNode->next;
}
Node *tNode = new Node;//新生节点,堆中申请内存
if(tNode == NULL){
return false;
}
tNode->data = pNode->data;
tNode->next = currentNode->next;//currentNode原先指向的节点赋给tNode指向的下个节点
currentNode->next = tNode;//currentNode指向tNode
m_iLength++;
return true;
}
bool List::listDelete(int i, Node *pNode){
if(i < 0 || i >= m_iLength){
return false;
}
Node *currentNode = m_pList;
Node *currentNodeBefore = NULL;
for(int j = 0; j <= i; j++){//多循环了一次,即删除的节点为currentNode!
currentNodeBefore = currentNode;
currentNode = currentNode->next;
}
currentNodeBefore->next = currentNode->next;//删除节点
pNode->data = currentNode->data;
delete currentNode;
currentNode = NULL;
m_iLength--;
return true;
}
bool List::listInsertHead(Node *pNode){
Node *t = m_pList->next;//临时节点
Node *tNode = new Node;//新生节点,堆中申请内存
if(tNode == NULL){
return false;
}
tNode->data = pNode->data;//新生节点的数据域
m_pList->next = tNode;//m_pList指向新生节点,即 第一个节点
tNode->next = t;//tNode指向 m_pList原先指向的节点
m_iLength++;
return true;
}
bool List::listInsertTail(Node *pNode){
Node *currentNode = m_pList;
while(currentNode->next != NULL){
currentNode = currentNode->next;
}
Node *tNode = new Node;//新生节点
if(tNode == NULL){
return false;
}
tNode->data = pNode->data;
tNode->next = NULL;
currentNode->next = tNode;
m_iLength++;
return true;
}
demo.cpp
#include"List.h"
#include"Coordinate.h"
#include<iostream>
//#include<string.h>
//#include<stdlib.h>
using namespace std;
int main(){
//测试
Node node1;//head
node1.data = 2;
Node node2;//tail
node2.data = 4;
Node node3;
node3.data = 3;
Node node4;
node4.data = 6;
List *list = new List;
list->listInsertHead(&node1);
list->listInsertTail(&node2);
list->listInsert(0,&node3);
list->listInsert(1,&node4);
cout << "遍历:" << endl;
list->listTraverse();
Node t;
list->priorElement(&node1,&t);
cout << node1.data << " 的前驱为:" << t.data << endl;
list->nextElement(&node1,&t);
cout << node1.data << " 的后继为:" << t.data << endl;
list->listDelete(0,&t);
cout << "删除的第一个节点:" << t.data << endl << endl;
cout << "删除后遍历:" << endl;
list->listTraverse();
delete list;
list = NULL;
system("pause");
return 0;
}
//控制台运行结果:
遍历:
3
6
2
4
2 的前驱为:6
2 的后继为:4
删除的第一个节点:3
删除后遍历:
6
2
4
//---------------------------------------------------------------------------
//-------------------------------------------------------------------------------