List.h:
//修改主要:
//1.将Elem改为Node
//2.加了两个操作:一个向头插入节点,一个向尾插入节点
#ifndef INC_0131_LIST_H
#define INC_0131_LIST_H
#include "Node.h"
class List
{
public:
List();//先放一个头节点,不需要size作为参数
~List();
void ClearList();//清空链表较为麻烦
bool ListEmpty();
int ListLength();
bool GetElem(int i, Node *pNode);//获取指定元素
int LocateElem(Node *pNode);//寻找第一个满足e的元素的位序
bool PriorElem(Node *pCurrentNode,Node *preNode);//获取指定元素的前驱
bool NextElem(Node *pCurrentNode,Node *pNextNode);//获取指定元素的后继
bool ListInsert(int i,Node *pNode);
bool ListDelete(int i,Node *pNode);
void ListTraverse();//遍历链表元素
bool ListInsertHead(Node *pNode);//插入头节点的下一个节点
bool ListInserTail(Node *pNode);//插入到最后一个节点
private:
Node *m_pList;
//int m_iSize;//链表不需要
int m_iLength;
};
#endif //INC_0131_LIST_H
List.cpp:
//n 2020-02-06.
//
#include "List.h"
#include <iostream>
#include "Node.h"
using namespace std;
//构造函数
List::List() {
m_pList = new Node;//头节点
m_pList->data = 0;//头节点的数据域没有意义
m_pList->next = NULL;
m_iLength = 0;//头节点不计入
}
void List::ClearList() {
//顺藤摸瓜式清除,先找头节点,直到找到指针域为空,用while循环
Node *currentNode = m_pList->next;
while(currentNode != NULL){
Node *tmp = currentNode->next;
delete currentNode;//释放掉当前currentNode的内存
currentNode = tmp;
}
//不要忘记将头节点的next置为0
m_pList->next = NULL;
}
//析构函数:将整个内存释放掉,
//与ClearList有异曲同工之处:~List需要将头节点和后续所有节点都释放掉,而ClearList不需要释放头节点
List::~List(){//可以利用已经写好的clearlist
ClearList();
delete m_pList;
m_pList =NULL;
}
bool List::ListEmpty() {
if(m_iLength == 0){
return true;
} else {
return false;
}
}
int List::ListLength(){
return m_iLength;
}
bool List::ListInsertHead(Node *pNode){
Node *tmp = m_pList->next;
Node *newNode = new Node;//一定要从堆中去申请内存,因为如果从栈中申请内存,函数执行完成之后这个内存就被回收了
//注意考虑内存申请失败的情况
if(newNode == NULL){
return false;
}
newNode->data = pNode->data;
m_pList->next = newNode;
newNode->next = tmp;
m_iLength++;
return true;
}
bool List::ListInserTail(Node *pNode){
Node *curentNode = m_pList;
while(curentNode->next != NULL){
curentNode = curentNode->next;
}
Node *newNode = new Node;
if(newNode == NULL){
return false;
}
newNode->data = pNode->data;
newNode->next = NULL;
curentNode->next = newNode;
m_iLength++;
return true;
}
bool List::ListInsert(int i,Node *pNode){
if(i < 0 || i > m_iLength){
return false;
}
Node *currentNode = m_pList;
for(int k = 0;k < i;k++){
currentNode = currentNode->next;
}
//自己写:找到插入的位置
Node *newNode = new Node;
if(newNode == NULL){
return false;
}
// newNode = currentNode->next;
// currentNode->next = pNode;
// pNode->next = newNode;
//错误,为什么?
newNode->data = pNode->data;
newNode->next = currentNode->next;
currentNode->next = newNode;
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 k = 0;k <= i ;k++){
currentNodeBefore = currentNode;
currentNode = currentNode->next;
}
currentNodeBefore->next = currentNode->next;
pNode->data = currentNode->data;
delete currentNode;
currentNode = NULL;
m_iLength--;
}
bool List::GetElem(int i, Node *pNode){
if(i < 0 || i >= m_iLength){
return false;
}
Node *currentNode = m_pList;
Node *currentNodeBefore = NULL;
for(int k = 0;k <= i ;k++){
currentNodeBefore = currentNode;
currentNode = currentNode->next;
}
pNode->data = currentNode->data;
return true;
}
int List::LocateElem(Node *pNode){
Node *currentNode = m_pList;
int i = 0;
while(currentNode->next != NULL){
currentNode = currentNode->next;//对链表进行遍历,对比数据域
//i++;不应该写在这里,只有不相同时才++
if(currentNode->data == pNode->data) {//返回什么?位置?而且只返回第一个符合的值(可能有多个)
return i;
}
i++;//不写在if语句之前,因为m_pList的数据域无效。
}
//如果一个节点都没有找到,易忽略
return -1;
}
bool List::PriorElem(Node *pCurrentNode,Node *preNode){
Node *currentNode = m_pList;
Node *tempNode = NULL;
while(currentNode->next != NULL){
tempNode = currentNode;
currentNode = currentNode->next;
if(currentNode->data == pCurrentNode->data){
if(tempNode == m_pList){//如果当前节点的前驱是头节点
return false;
}
preNode->data = tempNode->data;
return true;
}
}
}
bool List::NextElem(Node *pCurrentNode,Node *pNextNode){
Node *currentNode = m_pList;
while(currentNode->next != NULL){
currentNode = currentNode->next;
if(currentNode->data == pCurrentNode->data){
if(currentNode->next == NULL){
return false;
}
pNextNode->data = currentNode->next->data;
return true;
}
}
}
void List::ListTraverse(){
Node *currentNode = m_pList;
while (currentNode->next != NULL){
currentNode = currentNode->next;
currentNode->printNode();
}
}
Node.h:
//
// Created by w on 2020-02-07.
//
#ifndef INC_0131_NODE_H
#define INC_0131_NODE_H
class Node{
public:
int data;//数据域,直接写在public下边就是为了方便付值
Node *next;//指针域
void printNode();
};
#endif //INC_0131_NODE_H
Node.cpp:
//
// Created by x on 2020-02-07.
//
#include <iostream>
#include "Node.h"
using namespace std;
void Node::printNode(){
cout << data <<endl;
}
main.cpp:
#include <iostream>
#include <stdlib.h>
#include "List.h"
using namespace std;
//int a=3,b=5 ;
//printf( "max=%d\n" , max(a,b) ); //这里的a,b就是实参
//int max( int a , int b ) ;//这里的a,b就是形参
//在main函数中
// 调用函数swap(&a,&b);
//定义函数时:
//void swap(int *a, int *b);
//这个是配套使用的。
int main(){
Node node1;//括号加了会出错?why?
node1.data = 3;
Node node2;//括号加了会出错?why?
node2.data = 4;
Node node3;//括号加了会出错?why?
node3.data = 5;
Node node4;//括号加了会出错?why?
node4.data = 6;
List *pList = new List();
Node node5;
node5.data =7;
Node tmp;
// pList->ListInsertHead(&node1);
// pList->ListInsertHead(&node2);
// pList->ListInsertHead(&node3);
// pList->ListInsertHead(&node4);
// pList->ListTraverse();
pList->ListInserTail(&node1);
pList->ListInserTail(&node2);
pList->ListInserTail(&node3);
pList->ListInserTail(&node4);
pList->ListInsert(1,&node5);
// pList->ListDelete(1,&tmp);
pList->PriorElem(&node5,&tmp);
pList->ListTraverse();
cout << "tmp = " << tmp.data <<endl;
delete pList;
pList = NULL;
return 0;
}