数据结构之单链表(C++实现)

很早前就想用C++来实现那些常用的数据结构。

今天就算是个开端把。还是那句话,看的再多不如自己动手写一遍。

按照自己的思路写。首先你得熟悉那种结构的特点,然后才能谈实现。

 链表是一种很常用的数据结构。支持在任意地方对数据进行增删改查。

但是不支持随机访问。所以复杂度就有些高了。写的时候出了个问题。

最后把内存查看了几遍。并不是保存数据的结点出问题了。而是在链表转置

的时候用到的那个int *p = new int(length).出问题了。因为习惯了C的malloc,

所以就那么写。最后才发现这样并没有申请到需要的lenght个int长度的内存。

把()改成[]就好了。所以只有多用才能发现更多的错误。否则永远停留在理论层面上,

没有实践,貌似就是扯淡。

Link的功能不多,就那么些。当然你可以扩展。

gcc和vc6.0下通过。一个.cpp文件对应一个.h文件这样的规范比较好。

.h里面的函数如果很小就可以写出来,如果比较大,就写在.cpp文件里面。

以后会陆陆续续实现那些常用的数据结构C++版本。

你们的访问和评论是俺前进的强大动力啊。所以,亲啊,试试多花几秒钟在键盘上写写你的对问题

的看法。大笑

转载请注明出处,谢谢!

 Link.h

#ifndef LINK_H
#define LINK_H
//结构体的定义
struct myLink{
	int value;	//数据域
	struct myLink *next;	//指针域
};
class Link{
private:
	struct myLink *head;	//头指针
	struct myLink *cur;	//当前位置的指针
	int length;	//link的长度
public:
	Link(){//default constructor
		head = cur =NULL;	//默认link是空的
		length = 0;
	}
	Link(const Link &L){//禁止copy constructor
		throw "not allowed";
	}
	Link& operator=(const Link &L){//禁止assignment constructor
		throw "not allowed";
	}
	void add(int data);//添加元素到链表,默认到尾部添加
	int getData(int pos);//得到第pos位置的元素
	int remove(int pos);//移除某个位置的元素
	void sort();//对link进行排序
	int insert(int pos, int data);//在第pos个位置data插入到link
	void reverse();//对link进行转置
	void display();//对link的元素进行显示
	int modify(int pos, int data);//更改第pos个位置的data
	int getLength(){//得到link的长度
		return length;
	}
	~Link();	//destructor
};
#endif	

Link.cpp

#include <iostream>
#include "Link.h"

void Link::add(int data){
	struct myLink *u = new struct myLink;
	u->value = data;
	u->next = NULL;
	if (NULL == head){//头结点也存储数据
		head = u;
		cur = u;
	}else {
		cur->next = u;
		cur = u;	//当前指针改为u
	}
	length++;
}
int Link::getData(int pos){
	if (length >= pos && length > 0){//链表非空并且无越界
		int count = 0;//计数
			while (pos != count){
				count++;
				if (1 == count)
					cur = head;//头指针成为当前指针
				else
					cur = cur->next;//指针后移
			}
		return cur->value; 
	}
	return -1;	//其它返回-1
}
int Link::remove(int pos){
	if (length >= pos && length > 0){//链表非空并且无越界
		int count = 1;//计数
		while (pos != count){//得到第pos位置的前一个指针
			count++;
			if (2 == count)
				cur = head;//头指针成为当前指针
			else
				cur = cur->next;//指针后移
		}
		struct myLink *temp;
		if (1 == count){
			//如果remove第一个数据,就应该特殊处理下,因为头结点也存储了data
			temp = head; 
			head = temp->next;
			delete temp;
		}else {
			temp = cur->next;
			cur->next = temp->next;
			delete temp;
		}
		length--;	//不要忘了将length--
		return 0;
	}
	return -1;//其它返回-1
}
int Link::insert(int pos, int data){
	if (length >= pos && length > 0){//链表非空并且无越界
		int count = 1;//计数
		while (pos != count){//找到当前位置的前一个指针
			count++;
			if (2 == count)
				cur = head;//头指针成为当前指针
			else
				cur = cur->next;//指针后移
		}
		struct myLink *u = new struct myLink;
		u->value = data;
		if (1 == count){
			u->next = head;
			head = u;//当前结点成为头结点
		}else {
			u->next = cur->next;//新加结点的指向当前结点的下一个结点
			cur->next = u;	//当前结点指向新加结点
		}
		length++;	//不要忘了
		return 0; 
	}
	return -1;//其它返回-1
}
void Link::sort(){
	if (length > 1){
		int count = 0;
		while (length - 1 != count){
			int i = count + 1;
			struct myLink *temp = head;
			cur = head;	//当前结点指向头结点
			while (length != i ){
				if (cur->value > cur->next->value){
					cur->value += cur->next->value;
					cur->next->value = cur->value - cur->next->value;
					cur->value -= cur->next->value;
				}
				cur = cur->next; 
				i++;
			}
			temp = temp->next;
			count++;
		}
	}
}
void Link::reverse(){//通过改变指针域来转置,效率更高点
	if (length > 0){
		int count = 0;
		int *p = new int[length];//不要写成new int(length),最后俺找了2个多小时才找出来这里出错了
		//new int(length)没有申请length个int的内存,
		cur = head;	//当前结点指向头结点
		while (length != count){
			p[count] = (int)cur;//将指针存储在p[i]中
			count++;
			cur = cur->next;
		}
		count = 0;
		struct myLink *temp = head;	//辅助指针
		while (length != count){
			count++;
			cur = (struct myLink *)p[length - count];//反转
			if (1 == count){
				head = cur;//最后一个结点成为头结点
				temp = head;
			}
			else {
				temp->next = cur;	//当前结点成为上一个结点的后继结点
				temp = temp->next;	//temp后移
			}
		}
		cur->next = NULL;
		delete []p;
	}
}
int Link::modify(int pos, int data){
	if (length >= pos && length > 0){//链表非空并且无越界
		int count = 0;//计数
		while (pos != count){
			count++;
			if (1 == count)
				cur = head;//头指针成为当前指针
			else
				cur = cur->next;//指针后移
			}
		cur->value = data;
		return 0; 
	}
	return -1;//其它返回-1
}
void Link::display(){
	if (length > 0){
		std::cout<<"data in the Link is:"<<std::endl;
		int count = 0;
		cur = head;	//当前结点指向头结点
		while (length != count){
			count++;
			std::cout<<"the "<<count<<" data is "<<cur->value<<std::endl;
			cur = cur->next;
		}
	}
}
Link::~Link(){
	if (NULL != head){
		cur = head;	//从头结点开始delete
		while (0 != length){
			head = cur->next;	//头结点后移
			delete cur;
			cur = head;
			length--;
		}
	}
}



 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值