数据结构 单链表 头插 尾插 指定位置前插后插 以及 删除指定元素 C++ 面向对象方法实现

// 该内容来自http://stackoverflow.com/questions/22141477/simple-linked-list-c

// 经修改后得到(增加了尾插,指定位置前插、后插以及删除等功能)

List.h头文件:

<span style="font-size:12px;">/*
 * List.h
 *
 *  Created on: 2015-11-23
 *      Author: John
 */

#ifndef LIST_H_
#define LIST_H_
#include <iostream>
#include <stdlib.h>		// NULL ,也可以用0替代
typedef int ElementType;

using namespace std;
class List {
private:
	// Structure inside the class LinkedList
	// This is one node which is not needed by the caller. It is just
	// for internal work.
	/*** 节点类 ***/
	class Node{
	public:
		ElementType data;
		Node* next;
	};

// public member
public:
	/*** List 的函数成员 ***/
	// constructor
	List();
	void addValue(int val);
	void AddValueTail(int val);	// 尾插入
	void AddValuePrepend(int specValue, int val); // 在指定值前面插入
	void AddValueAppend(int specValue, int val); // 在指定值后面插入

	int popValue();
	void deleteValue(int val);
	// ①传入引用 ostream &out
	// ② const 表示这个函数是一个“只读函数”,函数不能改变类对象的状态,不能改变对象的成员变量的值
	// 更多阅读: http://blog.csdn.net/changrui82/article/details/6184502
	void display(ostream & out)const;
// private member
private:
	/*** List 的数据成员 ***/
	// 这个是私有的成员变量,他指向第一个节点。
	// this is the private member variable. It is just a pointer to the first Node
	Node* head;
};

// 重载输出操作符<< 用来出书List列表的内容
ostream & operator <<(ostream &out, const List & aList);

#endif /* LIST_H_ */
</span>
List.cpp源文件:
/*
 * List.cpp
 *
 *  Created on: 2015-11-23
 *      Author: John
 */
//  http://stackoverflow.com/questions/22141477/simple-linked-list-c
#include "List.h"

List::List() {
	// TODO Auto-generated constructor stub
	head = NULL;
}


// 使用头插法在list的开始位置插入节点
// This prepends a new value at the beginning of the list
void List::addValue(int val){
	Node * n = new Node();	// create new Node 创建一个新的节点
	n->data = val;			// set value	        设置值
	n->next = head;			// make the node point to the next node. 将新节点指向另一个节点
							// If the list is empty, this is NULL, so the end of the list --> OK
							// 如果list为空,那么head的值为NULL,n->next的值也为NULL,该节点就是List的最后一个节点
	head = n;				// last but not least, make the head point at the new node.
							// 最后,让head节点指向新创建的节点。
}

// 尾插 就应该叫 append吧。
void List::AddValueTail(int val){
	Node * n = new Node();
	n->data = val;
	n->next = NULL;

	Node * temp = head;
	if(head==NULL){
		head = n;
	}else{
		while(temp->next){
			temp=temp->next;
		}
		temp->next = n;
	}
}
// 在指定值前面插入
void List::AddValuePrepend(int specValue, int val){
	Node * temp = head;
	if(head->data == specValue){		// 就是头插
		addValue(val);
	}else{
		while(temp->next){
			if(temp->next->data == specValue){
				break;
			}
			temp=temp->next;
		}
		if(temp->next->data == specValue){
			Node * n = new Node();
			n->data = val;
			n->next = temp->next;
			temp->next = n;
		}
	}
}

// 在指定值后面插入
void List::AddValueAppend(int specValue, int val){
	Node * temp = head;
	while(temp){
		if(temp->data == specValue){
			break;
		}
		temp = temp->next;
	}
	if(temp->data == specValue){
		Node * n = new Node();
		n->data = val;
		n->next = temp->next;
		temp->next = n;
	}else{
		cout << "没有值" << specValue << endl;
	}
}

// 返回列表中第一个元素,并删除这个节点
// returns the first element in the list and deletes the Node.
// caution, no error-checking here!
int List::popValue(){
	Node * n = head;
	if(head){
		int ret = n->data;

		head = head->next;
		delete n;
		return ret;
	}
							// C/C++中如何获得int的最大值
	unsigned int temp = 0;	//http://blog.csdn.net/sanqi322/article/details/6321129
	return (~temp)/2+1;		// 返回int最小值(使用最大有符号int,然后将其1溢出后的值)
	// 获取最大值最小值的另一个参考http://blog.csdn.net/xuexiacm/article/details/8122267
}

void List::deleteValue(int val){
	Node *temp = head;
	if(head){
		if(head->data == val){
			head = head->next;
			delete temp;
		}else{
			while(temp->next){
				if(temp->next->data==val){
					Node * delPtr = temp->next;
					temp->next = temp->next->next;
					delete delPtr;
					break;
				}
				temp = temp->next;
			}
		}
	}else{

	}
}


void List::display(ostream & out)const{
	Node * temp = head;
	while(temp){
		out << temp->data <<"	" ;
		temp = temp->next;
	}
}

// 非成员函数,故没有List::限制符号
ostream & operator <<(ostream &out, const List & aList){
	aList.display(out);
	return out;
}

List_test.cpp测试:

/*
 * List_test.cpp
 *
 *  Created on: 2015-11-23
 *      Author: John
 */

#include "List.h"

#include <iostream>
using namespace std;
int main(){

	// 头插
	List linkList;
	linkList.addValue(5);
	linkList.addValue(10);
	linkList.addValue(15);

	cout<<"头插法建立的linkList链表元素为:"<<linkList<<endl;

	cout<< linkList.popValue() <<endl;
	cout<< linkList.popValue() <<endl;
	cout<< linkList.popValue() <<endl;
	// 因为在popValue()函数里面没有错误检测,
	// 下面的语句将会导致不确定的行为
	// 程序有可能会崩溃,因为list没有用来弹出的值了。
	// because there is no error checking in popValue(), the following
	// is undefined behavior. Probably the program will crash, because
	// there are no more values in the list.
	// cout << list.popValue() << endl;
	cout<< linkList.popValue() <<endl;	// 多弹出的一个元素


	// 尾插
	List linkListTail;
	linkListTail.AddValueTail(5);
	linkListTail.AddValueTail(10);
	linkListTail.AddValueTail(15);
	cout<<"尾插法建立的linkListTail链表元素为:"<<linkListTail<<endl;

	cout<< linkListTail.popValue() <<endl;
	cout<< linkListTail.popValue() <<endl;
	cout<< linkListTail.popValue() <<endl;
	cout<< linkListTail.popValue() <<endl;	// 多弹出的一个元素

	// 指定位置插入
	List linkListOther;
	linkListOther.addValue(5);
	linkListOther.addValue(10);
	linkListOther.addValue(15);
	cout<<"当前linkListOther链表元素为:";
	cout<<linkListOther<<endl;

	cout << "在指定值之前插入,输入指定位置的值(-999停止录入):";
	int number;
	cin>> number;
	int val;

	while(number!=-999){
		cout<< "输入插入的值:" ;
		cin>>val;
		linkListOther.AddValuePrepend(number,val);
		cout<<"指定元素"<<number<<"之前插入了"<<val<<"之后,列表元素为:";
		cout <<linkListOther<<endl;
		cout<< "输入插入的位置值:" ;
		cin >> number;

	}

	List linkListAother;
	linkListAother.addValue(5);
	linkListAother.addValue(10);
	linkListAother.addValue(15);
	linkListAother.addValue(20);
	linkListAother.addValue(25);
	linkListAother.addValue(30);
	cout<<"当前linkListAother链表元素为:";

	cout<<linkListAother<<endl;
	cout<<"输入要删除的元素的值(-999结束删除)";
	int val1;

	while(val1!=-999){
		cin>>val1;
		linkListAother.deleteValue(val1);
		cout<<"删除元素"<<val1<<"之后,列表元素为:";
		cout <<linkListAother<<endl;
		cout<<"输入要删除的元素的值(-999结束删除)";
	}
}

测试输出Output:

头插法建立的linkList链表元素为:15	10	5	
15
10
5
-2147483648
尾插法建立的linkListTail链表元素为:5	10	15	
5
10
15
-2147483648
当前linkListOther链表元素为:15	10	5	
在指定值之前插入,输入指定位置的值(-999停止录入):10
输入插入的值:9
指定元素10之前插入了9之后,列表元素为:15	9	10	5	
输入插入的位置值:15
输入插入的值:13
指定元素15之前插入了13之后,列表元素为:13	15	9	10	5	
输入插入的位置值:15
输入插入的值:14
指定元素15之前插入了14之后,列表元素为:13	14	15	9	10	5	
输入插入的位置值:5
输入插入的值:3
指定元素5之前插入了3之后,列表元素为:13	14	15	9	10	3	5	
输入插入的位置值:-999
当前linkListAother链表元素为:30	25	20	15	10	5	
输入要删除的元素的值(-999结束删除)20
删除元素20之后,列表元素为:30	25	15	10	5	
输入要删除的元素的值(-999结束删除)30
删除元素30之后,列表元素为:25	15	10	5	
输入要删除的元素的值(-999结束删除)25
删除元素25之后,列表元素为:15	10	5	
输入要删除的元素的值(-999结束删除)5
删除元素5之后,列表元素为:15	10	
输入要删除的元素的值(-999结束删除)10
删除元素10之后,列表元素为:15	
输入要删除的元素的值(-999结束删除)15
删除元素15之后,列表元素为:
输入要删除的元素的值(-999结束删除)0
删除元素0之后,列表元素为:
输入要删除的元素的值(-999结束删除)-999
删除元素-999之后,列表元素为:
输入要删除的元素的值(-999结束删除)




你可能感兴趣的:(数据结构,C++,面向对象,单链表)