刚开始弄C++,有些地方写的不好,希望批评指针,同时也给刚学数据结构的朋友一点指导,都是很简单的道理和写法。第一次写超过200行的代码,有点小激动就贴上来了,有点累。。先这样了。
//list.h
#ifndef LIST_H
#define LIST_H 1
#include <iostream>
using namespace std;
typedef int T;
typedef unsigned int size_t;
class List
{
struct Node
{
T data;
Node* next;
Node(const T& d=T()):data(d),next(NULL){/*cout << "构造了" << this << "$ ";*/}//d=T() 是0初始化
~Node(){/*cout << "析构了" << this << "~ ";*/}
};
Node* head;//定义头结点
int len;//定义链表的节点个数
public:
List();//构造函数
~List();//析构函数
List(const List& l);//拷贝构造函数
void insert(const T& data,int pos);//在指定位置插入数据
void push_front(const T& data);//头结点插入
void push_back(const T& data);//尾插入
void erase(int pos);//删除指定位置的节点
void remove(const T& data);//删除制定值的节点
void update(const T& data,int pos);//更新数据
Node*& getptr(int pos);//查找pos处的节点,0是头结点,1是第一个节点后面,返回指向他的指针
int find(const T& data);//查找值为data的节点,返回他的下标,0表示第一个;
void reverse();//反转链表
void sort();//排序链表
void clear();//清空链表
size_t size();//链表大小
bool empty();//是否为空
void travel();//遍历链表
T& get_front();//取头节点
T& get_back();//取尾
void swap(Node*& a,Node*& b);//交换两个节点的位置
void swap(const int lpos,const int rpos);//直接交换俩位置的数据
};
#endif
#include "stdafx.h"
#include "list.h"
#include <iostream>
using namespace std;
List::List() :head(NULL),len(0){}
List::~List(){clear();}
List::List(const List &l){//拷贝构造函数,先不写,开始没思路
head = NULL;
len=0;
Node* p=l.head;
while (p)
{
this->push_back(p->data);
p=p->next;
}
}
List::Node*& List::getptr(int pos)
{
if (pos < 0 || pos > len)
cout << "操作失败,越界了" << endl;
if(pos == 0) return head;//如果pos是0,直接返回头结点
Node* p = head;
for (int i = 1;i < pos;++i)
{
p=p->next;
}
return p->next;//这里一定要这要,因为我们要的是原始指针,并且返回值也是引用,
//如果返回p哪怕那个地址是我们要的,也要用p->next;要不就用二级指针
}
int List::find(const T& data)
{
Node* p=head;
int cnt=0;
while(p)
{
if (p->data==data)
return cnt;//这里用的是下标1表示第一个元素,不是0
p = p->next;
++cnt;
}
return -1; //没有找到就返回-1;
}
void List::insert(const T &data, int pos)
{
if(pos > =len) return ;
Node*& p=getptr(pos);
//cout << "p=" << p << endl;
Node* pn=new Node(data);
pn->next=p;
p=pn;
++len;
}
void List::push_front(const T &data)
{
insert(data,0);
}
void List::push_back(const T& data)
{
insert(data,len);
}
void List::clear()
{
Node*p =head;
while (p)
{
p=p->next;//先保存头结点的下一个节点,再删除头结点
// cout << head << ' ';
delete head;
head=p;
}
// cout << endl;
len=0;
}
void List::travel()
{
Node* p=head;
while (p)
{
cout << p->data << ' ';
p=p->next;
}
cout << endl;
}
void List ::erase(int pos)
{
Node*& pn=getptr(pos);
Node* p=pn;//保存一份找到的节点这个要删除的
pn=pn->next;
delete p;
--len;
}
void List::remove(const T& data)
{
int n=find(data);
while (n!=-1)
{
erase(n);
n=find(data);//防止有重复的
}
}
bool List::empty(){
return head==NULL;
}
T& List::get_front()
{
return head->data;
}
T& List::get_back()
{
Node*& pn=getptr(len-1);
return pn->data;
}
void List::update(const T& data,int pos)
{
Node*& pn=getptr(pos);
pn->data=data;
}
size_t List::size()
{
return len;
}
void List::reverse() //有点偷鸡的味道,先这样好了。不管做什么操作,链表的头指针不能动。
{
List L;
for(int i=len-1;i >= 0 ;i--)
L.push_back(getptr(i)->data);
L.travel();
}
void List::swap(Node*& a,Node*& b)
{
/*
int n = find(a->data);
int m = find(b->data);
swap(n,m);
cout << "a=" << a->data << "b=" << b->data << endl;*/ //这样的代码有个问题,如果节点中有重复的元素,
//交换的位置就不对了
T temp = a->data;
a->data = b->data;
b->data = temp;//直接用的值交换,用指针交换也可以,在下面,当链表节点中存的复杂数据时,要考虑用指针交换如下面那个swap()函数,里面有指针交换
因为重写这个函数的话涉及到找准确下标的值就可以直接调用下面那个函数了太晚了,暂时不改了。
}
void List::swap(const int lpos,const int rpos)
{
Node*& lp=getptr(lpos);
Node*& rp=getptr(rpos);
/* T temp=lp->data;
lp->data=rp->data;
rp->data=temp; //值交换,这个是可以的。*/
Node* p1=lp;//保存下这俩节点
Node* p2=rp;
lp = lp->next;
rp = rp.next;
p2->next = p1;
}
void List::sort()
{
if(len==1) return ;
for (int i=1;i<len;i++)//简单点,就用冒泡了。链表有点绕
{
Node* p = head;
while (p)
{
if (p->next!=NULL)//判断有没有下个元素
{
if (p->data > p->next->data)
{
swap(p,p->next);
}
}
p=p->next;
}
}
}