数据结构 之 线性表中的链表

直接上代码了。。


List.h

#ifndef LIST_H
#define LIST_H

#include"Node.h"
//class Node;
class List
{
public:
	List();
	~List();
	void clearList();//清空表
	bool listEmpty();//判断是否为空表
	int listLength();//表元素长度
	bool getNode(int i,Node *e);//获得第i(0开始)个元素赋值给e
	int locateNode(Node *e);//找出与e相等的元素并返回元素下标
	bool priorNode(Node* currentNode,Node* preNode);//用指针类型可以节省空间,找到和当前元素一样的值的元素的前一个元素赋给preNode
	bool nextNode(Node* currentNode,Node* nextNode);
	bool listInsert(int i,Node*e);//在i位置插入元素
	bool listDelete(int i,Node *e);//删除i位置元素
	void listTraverse();//遍历
	bool listInsertHead(Node* e);
	bool listInsertTail(Node* e);
private:
	Node *m_pList;
	int m_iLength;
};



#endif

List.cpp


#include"List.h"
#include"Node.h"
#include<iostream>
using namespace std;

List::List()
{
	m_pList = new Node;
	//m_pList->data = 0;
	m_pList->next = NULL;//空链表表示只有一个表头
	m_iLength = 0;
	cout << "List<Node>::List(int size)" << endl;
}

List::~List()//表头也被释放了
{
	clearList();
	delete m_pList;
	m_pList = NULL;

}

void List::clearList()//回到空链表状态(只剩表头)
{
	if(!listEmpty()){
		Node *p1,*p2;
		p1 = m_pList->next;
		while(p1 != NULL){
			p2 = p1->next;
			delete p1;
			p1 = p2;
		}
		m_pList->next = NULL;
		m_iLength = 0;

	}
}

bool List::listEmpty()
{
	if(m_iLength == 0)return true;
	return false;
}

int List::listLength()
{
	return m_iLength;
}

bool List::getNode(int i,Node *e)
{
	if((i >= 0)&&(m_iLength > i)){
		//*e = m_pList[i];
		Node *currentNode = m_pList->next;
		for(int j = 0;j < i;j++){
			currentNode = currentNode->next;
		}
		e->data = currentNode->data;
		return true;
	}else{
		return false;
	}
}

int List::locateNode(Node *e)
{
	//int i;
	//for(i = 0;i < m_iLength;i ++){
	//	if(*e == m_pList[i]){
	//		return i;
	//	}
	//}
	int index = 0;
	Node *currentNode = m_pList->next;
	while((currentNode != NULL) && (currentNode->data != e->data)){
		currentNode = currentNode->next;
		index++;
	}
	if(currentNode == NULL){
		cout << "没有相同的元素" << endl;
		return -1;//下标不会小于0
	}else{
		return index;
	}
	
}

bool List::priorNode(Node* currentNode,Node* preNode)
{
	int temp = locateNode(currentNode);//取名temp因为它是一个临时的返回值
	Node *p = m_pList->next;
	if(temp > 0){
		for(int i = 0;i < temp-1;i++){
			p = p->next;
		}
		preNode->data = p->data;
		return true;
	}else{
		return false;
	}

}

bool List::nextNode(Node* currentNode,Node* nextNode)
{
	int temp = locateNode(currentNode);//取名temp因为它是一个临时的返回值
		Node *p = m_pList->next;
		if((temp >= 0)&&(temp < m_iLength-1)){
			for(int i = 0;i < temp+1;i++){
				p = p->next;
			}
			nextNode->data = p->data;
			return true;
		}else{
			return false;
		}


}

void List::listTraverse()
{
	if(!listEmpty()){
		Node *p = m_pList->next;
		while(p != NULL){
			cout << p->data;
			cout << endl;
			p = p->next;
		}
		cout << endl;
	}else{
		cout << "空表!" << endl;
	}
}

bool List::listInsert(int i,Node*e)
{
	if((i >= 0)&&(i <= m_iLength)){
		Node *newNode = new Node;
		if(newNode == NULL){
			return false;
		}
		newNode->data = e->data;
		Node *temp = m_pList;
		for(int j = 0;j < i;j++){
			temp = temp->next;
		}
		newNode->next = temp->next;
		temp->next = newNode;
		m_iLength ++;//别忘了!
		return true;
	}else{
		return false;
	}
}

bool List::listDelete(int i,Node *e)
{
	if((i >= 0)&&(i < m_iLength)&&(!listEmpty())){
		Node *temp = m_pList;
		for(int j = 0;j < i;j++){
			temp = temp->next;
		}
		Node *delNode = temp->next;
		temp->next = temp->next->next;
		e->data = delNode->data;
		delete delNode;
		delNode = NULL;
		m_iLength --;
		return true;
	}else{
		return false;
	}
}

bool List::listInsertHead(Node* e)//只用e的data
{
	Node *newNode = new Node;
	if(newNode == NULL){//申请失败
		return false;
	}
	newNode->data = e->data;
	newNode->next = m_pList->next;
	m_pList->next = newNode;
	m_iLength ++;//别忘了!
	return true;
}

bool List::listInsertTail(Node* e)
{
	Node *p = m_pList;
	while(p->next != NULL){
		p = p->next;
	}
	Node *newNode = new Node;//申请新内存
	while(newNode == NULL){
		return false;
	}
	p->next = newNode;
	newNode->data = e->data;//只是将e的data赋值过来,而不是直接将e加入
	newNode->next = NULL;
	m_iLength ++;//别忘了!
	return true;
}

Node.h

#ifndef NODE_H
#define NODE_H

#include"Person.h"//实验后发现比下一句好,如果用下一句,则Person data;会显示不允许使用不完整的定义
//class Person;
class Node
{
public://为了方便都定义在public下
	Person data;
	Node *last;
	Node *next;
	
	//Node();直接用默认
	//~Node();


};


#endif



Person.h


#ifndef PERSON_H
#define PERSON_H

#include<string>//因为有定义string类
#include<ostream>//因为用到了ostream,不写iostream能方便编译
using namespace std;

class Person
{
	friend ostream& operator << (ostream&, Person&);
public:
	bool operator != (Person&);
	//Person operator = (Person&);//不重载=也不会报错,因为person里面就name和phone两个简单的string类变量,但如果person有指针类变量,就必须要重载了,浅拷贝没有自己定义的深拷贝安全
	string name;
	string phone;

};







#endif


Person.cpp


#include"Person.h"


ostream& operator << (ostream& out, Person& person)//是一个全局函数,写在全局的任意位置都可以
{
	out << "姓名:" << person.name << endl;
	out << "电话:" << person.phone;
	return out;
}

bool Person::operator != (Person& person)
{
	if( (this->name == person.name) || (this->phone == person.phone) ){//非严格相等,只要名字和电话中有一者是相同的,则判断为两个person相同并返回false
		return false;
	}
	return true;
}

demo.cpp



#include<iostream>
#include<stdlib.h>
#include"List.h"
#include"Node.h"
#include"Person.h"
using namespace std;
//线性表(包括顺序表和链表)——动态链表 c++实现
//链表优点:改善了顺序表缺陷(插入和删除元素时,元素后面的所有元素都要移动)
//缺点:寻址取数据较麻烦
//以通讯录为例

int menu()
{
	cout << "通过录功能" << endl;
	cout << "1.新建联系人" << endl;
	cout << "2.删除联系人" << endl;
	cout << "3.浏览通讯录" << endl;
	cout << "4.退出通讯录" << endl;

	cout << "请输入:" << endl;

	int order = 0;
	cin >> order;
	return order;
}
void creatPerson(List *pList)
{
	Node node;
	Person person;
	cout << "输入姓名:" << endl;
	cin >> person.name;
	cout << "输入电话:" << endl;
	cin >> person.phone;
	node.data = person;
	pList->listInsertTail(&node);//create函数调用完后node就会被释放掉,所以insert函数定义里面一定是只取node的data的深拷贝方法。
}
void deletePerson(List *pList)
{
	Node node;
	Person person;
	cout << "待删人的姓名(不知道请输入0):" << endl;
	cin >> person.name;
	cout << "待删人的电话(不知道请输入x):" << endl;
	cin >> person.phone;
	node.data = person;
	int delIndex = pList->locateNode(&node);
	pList->listDelete(delIndex,&node);
}


int main(){
	int userOrder = 0;

	List *pList = new List();
	while(userOrder != 4)//不退出就可以一直循环
	{
		userOrder = menu();
		switch (userOrder)
		{
		case 1:
			cout << "用户指令--->>新建联系人:" << endl;
			creatPerson(pList);
			break;
		case 2:
			cout << "用户指令--->>删除联系人:" << endl;
			deletePerson(pList);
			break;
	    case 3:
			cout << "用户指令--->>浏览通讯录:" << endl;
			pList->listTraverse();
			break;
		case 4:
			cout << "用户指令--->>退出通讯录:" << endl;
			break;
		default:
			break;
		}



	}

	delete pList;
	pList = NULL;

system("pause");
return 0;
}




猜你喜欢

转载自blog.csdn.net/zealice/article/details/78538978