链式表的实现
2016-07-12 13:00
253 查看
最头两天开始实现数据结构到现在,这个代码敲了三个多小时,悲剧啊,都怪当初c++很多东西都没有扎实(本来就没怎么学);
List类实现了基本的增删改查,拷贝构造函数,重载运算符。在实现重载运算符使其支持对象赋值的过程中,一定要将数据成员完全复制!否则num数据成员就不准确了。
另外实现拷贝构造函数时,也要完全复制,另外当时突然想起来以前看 primer plus时 ,书上说过,内存中临时创建的对象并不会默认调用构造函数,所以可能导致num,等
数据成员为随机值。
另外我实现set_position_2()的时候利用保留当前位置的方法定位,一定要注意当我们在添加第一个结点的时候,也要把current指针指向添加的第一个元素,否则以后就没有办法来拿current来遍历定位了。然后当我们删除中间结点时,我们肯定要定位他的前驱结点,那么此时的current指针 和current_position是一个确切值然而当我删除第一个结点时,Remove()实现中并没有定位操作,所以删除的结点在current_position位置之前,那么删除之后,current指针
和current_position就不是一个确切值了,我们应该重置,使其再次确切。set_position_1()函数在实现中并没有遇到问题。
把两个定位操作函数放在protected中是因为,两个方法都要访问数据成员,并返回一个指向Node的指针,为了数据的安全性,我们把这两个定位方法声明为不可见的,并保证他
只能作为构造List其他方法时的可用工具;
const修饰能加的地方还是尽量要加上,确实在编译的时候能爆出很多可能潜在的错误。
以下是实现代码:
List.h:
[cpp]
view plain
copy
print?
/*=============================================================================
#
# Author: liangshu - cbam
#
# QQ : 756029571
#
# School : 哈尔滨理工大学
#
# Last modified: 2015-10-28 14:50
#
# Filename: 链式表的实现 - 副本.cpp
#
# Description:
# The people who are crazy enough to think they can change the world, are the ones who do !
=============================================================================*/
#
using namespace std;
enum Error_code {success, overflow, underflow, Range_error};
template<class Node_entry>
struct Node{
Node_entry Entry;
Node<Node_entry> * next;
Node();
Node(const Node_entry &item, Node<Node_entry> *link = NULL):Entry(item), next(link){}
};
template<class Node_entry>
Node<Node_entry>::Node(){
next = NULL;
}
template<class List_entry>
class List{
public:
List();
List(const List<List_entry> &Copy);
int Size_list()const{
return num;
}
bool Empty_list()const{
return num == 0;
}
void Clear();
Error_code retrieve(int position, List_entry &item)const;
Error_code Remove(int position, List_entry &item);
Error_code Replace(int position, const List_entry &item);
Error_code Insert(int position, const List_entry &item);
void operator = (const List<List_entry> &Copy);
void Print_list()const;
protected:
mutable int current_position;
mutable Node<List_entry> *current;
Node<List_entry>*head;
Node<List_entry>*set_position_1(int postion)const;
Node<List_entry>*set_position_2(int postion)const;
int num;
};
template<class List_entry>
List<List_entry>::List(){
num = current_position = 0;
head = NULL;
current = head;
}
template<class List_entry>
void List<List_entry>::Clear(){
while(!Empty_list()){
Node<List_entry> *old_head = head;
head = head -> next;
num--;
delete old_head;
}
current = NULL;
current_position = 0;
}
template<class List_entry>
List<List_entry>::List(const List<List_entry> &Copy){
Node<List_entry> *new_copy, *old_node = Copy.head;
if(old_node == NULL){
head = NULL;
}
else{
head = new_copy = new Node<List_entry>(old_node -> Entry,old_node -> next);
while(old_node -> next != NULL){
old_node = old_node -> next;
new_copy -> next = new Node<List_entry>(old_node -> Entry,old_node -> next);
new_copy = new_copy -> next;
}
}
num = Copy.num;
current = Copy.current;
current_position = Copy.current_position;
}
template<class List_entry>
Error_code List<List_entry>::retrieve(int position, List_entry &item)const{
if(position < 0 || position > num){
return Range_error;
}
Node<List_entry> *new_node = set_position_2(position);
item = new_node -> Entry;
return success;
}
template<class List_entry>
Error_code List<List_entry>::Remove(int position, List_entry &item){
if(position < 0 || position > num){
return Range_error;
}
Node<List_entry>*previous, *old_node;
if(position > 0){
old_node = previous = set_position_1(position - 1);
old_node = old_node -> next;
item = old_node -> Entry;
previous -> next = previous-> next -> next;
delete old_node ;
}
else{
old_node = head;
head = old_node -> next;
item = old_node -> Entry;
delete old_node;
current = head;
current_position = 0;
}
num--;
return success;
}
template<class List_entry>
Error_code List<List_entry>::Replace(int position, const List_entry &item){
if(position < 0 || position > num){
return Range_error;
}
List_entry x;
Remove(position, x);
Insert(position, item);
return success;
}
template<class List_entry>
void List<List_entry>::operator = (const List<List_entry> &Copy){
Node<List_entry> *new_head, *new_copy, *old_node = Copy.head;
if(old_node == NULL){
head = NULL;
}
else{
new_head = new_copy = new Node<List_entry>(old_node -> Entry,old_node -> next);
while(old_node -> next != NULL){
old_node = old_node -> next;
new_copy -> next = new Node<List_entry>(old_node -> Entry,old_node -> next);
new_copy = new_copy -> next;
}
}
while(!Empty_list()){
Node<List_entry> *old_head = head;
head = head -> next;num--;
delete old_head;
}
current = Copy.current;
current_position = Copy.current_position;
num = Copy.num;
head = new_head;
}
template<class List_entry>
Node<List_entry>* List<List_entry>::set_position_1(int position)const{
Node<List_entry> *q = head;
for(int i = 0; i < position; i++){
q = q -> next;
}
return q;
}
template<class List_entry>
Node<List_entry>* List<List_entry>::set_position_2(int position)const{
if(position < current_position){
current_position = 0;
current = head;
}
for(;current_position != position; current_position++){
current = current -> next;
}
return current;
}
template<class List_entry>
void List<List_entry>:: Print_list()const{
cout<<"| -- ";
Node<List_entry> *old_head = head;
while(old_head != NULL){
cout<<old_head -> Entry<<" -- ";
old_head = old_head -> next;
}
cout<<" |"<<endl;
}
template<class List_entry>
Error_code List<List_entry>::Insert(int position, const List_entry &item){
if(position < 0 || position > num){
return Range_error;
}
Node<List_entry> * new_node , *previous, *following;
if(position > 0){
previous = set_position_1(position - 1);
// previous = current;
following = previous -> next;
}
else{
following = head;
}
new_node = new Node<List_entry>(item, following);
if(new_node == NULL){
return overflow;
}
if(position == 0){
head = new_node;
current = head;
}
else{
previous -> next = new_node;
}
num ++;
return success;
}
Test.cpp:
[cpp]
view plain
copy
print?
#include<iostream>
#include"List.h"
using namespace std;
int main()
{
List<int>list_1, list_2, list_3;
for(int i = 1; i <= 5; i++){
list_1.Insert(i - 1, i);
}
int x;
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
list_1.retrieve(1, x);
cout<<x<<endl;
list_1.Remove(2, x);
cout<<"Remove ="<<x<<endl;
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
list_1.Replace(2, 100);
list_1.Print_list();
list_1.Remove(0, x);
cout<<"Remove2 = "<<x<<endl;
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
list_1.Insert(3,123456);
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
list_1.Clear();
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
for(int i = 1; i <= 9; i++){
list_1.Insert(i - 1, i);
}
list_1.Print_list();
list_2 = list_1;
list_2.Print_list();
cout<<"ci = "<<endl;
list_3 = List<int>(list_2);
list_3.Print_list();
list_3.Remove(3,x);
list_3.Print_list();
list_3.Insert(0,19999);
list_3.Insert(7, 1000009);
list_3.retrieve(9, x);
cout<<"x ="<<x<<endl;
list_3.Print_list();
return 0;
}
List类实现了基本的增删改查,拷贝构造函数,重载运算符。在实现重载运算符使其支持对象赋值的过程中,一定要将数据成员完全复制!否则num数据成员就不准确了。
另外实现拷贝构造函数时,也要完全复制,另外当时突然想起来以前看 primer plus时 ,书上说过,内存中临时创建的对象并不会默认调用构造函数,所以可能导致num,等
数据成员为随机值。
另外我实现set_position_2()的时候利用保留当前位置的方法定位,一定要注意当我们在添加第一个结点的时候,也要把current指针指向添加的第一个元素,否则以后就没有办法来拿current来遍历定位了。然后当我们删除中间结点时,我们肯定要定位他的前驱结点,那么此时的current指针 和current_position是一个确切值然而当我删除第一个结点时,Remove()实现中并没有定位操作,所以删除的结点在current_position位置之前,那么删除之后,current指针
和current_position就不是一个确切值了,我们应该重置,使其再次确切。set_position_1()函数在实现中并没有遇到问题。
把两个定位操作函数放在protected中是因为,两个方法都要访问数据成员,并返回一个指向Node的指针,为了数据的安全性,我们把这两个定位方法声明为不可见的,并保证他
只能作为构造List其他方法时的可用工具;
const修饰能加的地方还是尽量要加上,确实在编译的时候能爆出很多可能潜在的错误。
以下是实现代码:
List.h:
[cpp]
view plain
copy
print?
/*=============================================================================
#
# Author: liangshu - cbam
#
# QQ : 756029571
#
# School : 哈尔滨理工大学
#
# Last modified: 2015-10-28 14:50
#
# Filename: 链式表的实现 - 副本.cpp
#
# Description:
# The people who are crazy enough to think they can change the world, are the ones who do !
=============================================================================*/
#
using namespace std;
enum Error_code {success, overflow, underflow, Range_error};
template<class Node_entry>
struct Node{
Node_entry Entry;
Node<Node_entry> * next;
Node();
Node(const Node_entry &item, Node<Node_entry> *link = NULL):Entry(item), next(link){}
};
template<class Node_entry>
Node<Node_entry>::Node(){
next = NULL;
}
template<class List_entry>
class List{
public:
List();
List(const List<List_entry> &Copy);
int Size_list()const{
return num;
}
bool Empty_list()const{
return num == 0;
}
void Clear();
Error_code retrieve(int position, List_entry &item)const;
Error_code Remove(int position, List_entry &item);
Error_code Replace(int position, const List_entry &item);
Error_code Insert(int position, const List_entry &item);
void operator = (const List<List_entry> &Copy);
void Print_list()const;
protected:
mutable int current_position;
mutable Node<List_entry> *current;
Node<List_entry>*head;
Node<List_entry>*set_position_1(int postion)const;
Node<List_entry>*set_position_2(int postion)const;
int num;
};
template<class List_entry>
List<List_entry>::List(){
num = current_position = 0;
head = NULL;
current = head;
}
template<class List_entry>
void List<List_entry>::Clear(){
while(!Empty_list()){
Node<List_entry> *old_head = head;
head = head -> next;
num--;
delete old_head;
}
current = NULL;
current_position = 0;
}
template<class List_entry>
List<List_entry>::List(const List<List_entry> &Copy){
Node<List_entry> *new_copy, *old_node = Copy.head;
if(old_node == NULL){
head = NULL;
}
else{
head = new_copy = new Node<List_entry>(old_node -> Entry,old_node -> next);
while(old_node -> next != NULL){
old_node = old_node -> next;
new_copy -> next = new Node<List_entry>(old_node -> Entry,old_node -> next);
new_copy = new_copy -> next;
}
}
num = Copy.num;
current = Copy.current;
current_position = Copy.current_position;
}
template<class List_entry>
Error_code List<List_entry>::retrieve(int position, List_entry &item)const{
if(position < 0 || position > num){
return Range_error;
}
Node<List_entry> *new_node = set_position_2(position);
item = new_node -> Entry;
return success;
}
template<class List_entry>
Error_code List<List_entry>::Remove(int position, List_entry &item){
if(position < 0 || position > num){
return Range_error;
}
Node<List_entry>*previous, *old_node;
if(position > 0){
old_node = previous = set_position_1(position - 1);
old_node = old_node -> next;
item = old_node -> Entry;
previous -> next = previous-> next -> next;
delete old_node ;
}
else{
old_node = head;
head = old_node -> next;
item = old_node -> Entry;
delete old_node;
current = head;
current_position = 0;
}
num--;
return success;
}
template<class List_entry>
Error_code List<List_entry>::Replace(int position, const List_entry &item){
if(position < 0 || position > num){
return Range_error;
}
List_entry x;
Remove(position, x);
Insert(position, item);
return success;
}
template<class List_entry>
void List<List_entry>::operator = (const List<List_entry> &Copy){
Node<List_entry> *new_head, *new_copy, *old_node = Copy.head;
if(old_node == NULL){
head = NULL;
}
else{
new_head = new_copy = new Node<List_entry>(old_node -> Entry,old_node -> next);
while(old_node -> next != NULL){
old_node = old_node -> next;
new_copy -> next = new Node<List_entry>(old_node -> Entry,old_node -> next);
new_copy = new_copy -> next;
}
}
while(!Empty_list()){
Node<List_entry> *old_head = head;
head = head -> next;num--;
delete old_head;
}
current = Copy.current;
current_position = Copy.current_position;
num = Copy.num;
head = new_head;
}
template<class List_entry>
Node<List_entry>* List<List_entry>::set_position_1(int position)const{
Node<List_entry> *q = head;
for(int i = 0; i < position; i++){
q = q -> next;
}
return q;
}
template<class List_entry>
Node<List_entry>* List<List_entry>::set_position_2(int position)const{
if(position < current_position){
current_position = 0;
current = head;
}
for(;current_position != position; current_position++){
current = current -> next;
}
return current;
}
template<class List_entry>
void List<List_entry>:: Print_list()const{
cout<<"| -- ";
Node<List_entry> *old_head = head;
while(old_head != NULL){
cout<<old_head -> Entry<<" -- ";
old_head = old_head -> next;
}
cout<<" |"<<endl;
}
template<class List_entry>
Error_code List<List_entry>::Insert(int position, const List_entry &item){
if(position < 0 || position > num){
return Range_error;
}
Node<List_entry> * new_node , *previous, *following;
if(position > 0){
previous = set_position_1(position - 1);
// previous = current;
following = previous -> next;
}
else{
following = head;
}
new_node = new Node<List_entry>(item, following);
if(new_node == NULL){
return overflow;
}
if(position == 0){
head = new_node;
current = head;
}
else{
previous -> next = new_node;
}
num ++;
return success;
}
Test.cpp:
[cpp]
view plain
copy
print?
#include<iostream>
#include"List.h"
using namespace std;
int main()
{
List<int>list_1, list_2, list_3;
for(int i = 1; i <= 5; i++){
list_1.Insert(i - 1, i);
}
int x;
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
list_1.retrieve(1, x);
cout<<x<<endl;
list_1.Remove(2, x);
cout<<"Remove ="<<x<<endl;
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
list_1.Replace(2, 100);
list_1.Print_list();
list_1.Remove(0, x);
cout<<"Remove2 = "<<x<<endl;
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
list_1.Insert(3,123456);
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
list_1.Clear();
list_1.Print_list();
cout<<list_1.Size_list()<<endl;
for(int i = 1; i <= 9; i++){
list_1.Insert(i - 1, i);
}
list_1.Print_list();
list_2 = list_1;
list_2.Print_list();
cout<<"ci = "<<endl;
list_3 = List<int>(list_2);
list_3.Print_list();
list_3.Remove(3,x);
list_3.Print_list();
list_3.Insert(0,19999);
list_3.Insert(7, 1000009);
list_3.retrieve(9, x);
cout<<"x ="<<x<<endl;
list_3.Print_list();
return 0;
}
相关文章推荐
- javaweb项目多浏览器支持打印
- 69 个经典 Spring 面试题及答案
- Android JNI DETECTED ERROR IN APPLICATION的解决
- ORA-01017: invalid username/password; logon denied 解决办法
- 查找算法(二叉搜索树查找,二分查找,hash查找)
- js 文字预写匹配
- 移动端图片懒加载插件
- log4net的使用
- Animate.css 教程
- TestNG入门笔记[2] : 简介 & 基本注解 & 举例
- 常见排序和查找算法的实现
- ASCLL一览表
- 仓库管理中立体仓库的定义、特点和分类
- 使用ffmpeg实现转码样例(代码实现)
- 埙教程
- sdafsdfa
- 构建数据缓冲池
- bean的加载(九)记录创建bean的ObjectFactory
- js获取编辑框游标的位置
- Zabbix Appliance 3.0 用户名密码