这篇文章是关于严蔚敏清华版《数据结构》教材的代码,包括书上大纲规定的线性表,链表,栈,队列,二叉树,图,排序,
查找等基本算法的编码,还包括循环链表,广义表,两栈共享空间,字符串模式匹配等非常规,较难数据结构的编码,除此之外书本
后面大量的思考题,例如约瑟夫环,括号匹配,迷宫问题,八皇后,火车厢重排,斐波那契查找等一些列经典问题也有代码。文章中
的代码,均已调试通过,并附有程序运行结果,读者可以自行复制运行。
这是我用一个假期重学数据结构的劳动结果,希望此篇文章,能给初学数据局结构的同学以帮助,代码若有什么问题,可以
直接用QQ与我联系,感谢赐教。
由于整个篇幅较长,相关内容按照数据结构课本章节内容组织。下面是第一章,其他章节请参照其他博客。
第一章 线性表
#include <iostream>
using namespace std;
const int MaxSize=100;
#include <iomanip>
template <class T>
class SeqList
{
private:
T data[MaxSize];
int length;
public:
SeqList(T a[],int Length);
SeqList(){length=0;}
~SeqList();
T Get(int i);//按顺序查找
void Locate(T value);
T Delete(int i);
void Insert(int i,T value);
void PrintList();
};
template <class T>
SeqList<T>::SeqList(T a[],int Length)
{
if(Length>MaxSize) throw "参数非法!";
for (int i=0;i<Length;i++)
data[i]=a[i];
this->length=Length;
}
template <class T>
SeqList<T>::~SeqList()
{
//cout<<"调用析构函数!"<<endl;
}
template <class T>
void SeqList<T>::PrintList ()
{
if(this->length==0)cout<<"顺序表为空!"<<endl;
else
{
cout<<"***************************"<<endl;
int count=0;
for(int i=0;i<length;i++)
{
cout<<setw(3)<<data[i];
count++;
if(count%10==0)
cout<<endl;
}
cout<<endl;
}
}
template <class T>
T SeqList<T>::Get(int i)
{
cout<<"***************************"<<endl;
cout<<"第"<<i<<"个元素为:";
if(i<1 || i>length) throw"位置非法!";
else
return data[i-1];
}
template <class T>
void SeqList<T>::Locate (T value)
{
cout<<"***************************"<<endl;
int get[MaxSize]={0};
int count=-1;
for (int i=0;i<length;i++)
{
if(data[i]==value)
{
count++;
get[count]=i+1;
}
}
if(count==-1)
cout<<"顺序表中不存在值为"<<value<<"的元素"<<endl;
else
{
cout<<"值为"<<value<<"的元素的位置为:";
for(i=0;i<=count;i++)
cout<<setw(3)<<get[i];
cout<<endl;
}
}
template <class T>
void SeqList<T>::Insert (int i,T value)
{
if(i<1 || i>length)throw"插入位置异常!";
for(int j=length-1;j>=i-1;j--)
data[j+1]=data[j];
data[i-1]=value;
length++;
}
template <class T>
T SeqList<T>::Delete (int i)
{
cout<<"***************************"<<endl;
cout<<"删除的元素为:";
if(i<1 || i>length)throw"删除位置异常!";
T DelValue=data[i-1];
for(int j=i;j<=length-1;j++)
data[j-1]=data[j];
length--;
return DelValue;
}
void main()
{
cout<<"----------顺序表实验------------"<<endl;
int a1[10]={0,1,2,5,4,5,6,5,8,9};
SeqList<int> S1(a1,10);
S1.PrintList();
S1.Locate(5);
cout<<S1.Get(5)<<endl;
S1.Insert (4,21);
S1.PrintList();
cout<<S1.Delete(4)<<endl;
S1.PrintList();
}
//关于单链表重点理解:头指针是一个单链表存在的唯一标示,故而一切操作均从头结点开始展开
#include <iostream>
using namespace std;
template <class T>
struct Node
{
T data;
Node<T> *next;
};
template <class T>
class LinkList
{
private :
Node<T> *first;
public:
LinkList(T a[],int n);
LinkList();
~LinkList();
void PrintList();
int Length();
int Locate(T value);
T Get(int location);
void Insert(T value,int location);//将值为value的节点插入到第location个位置
T Delete (int location);
};
//无参构造函数:建立一个空链表
template <class T>
LinkList<T>::LinkList()
{
first =new Node<T>;
first->next=NULL;
}
//析构函数:一个一个释放单链表的节点动态开辟的空间
template <class T>
LinkList<T>::~LinkList()
{
//cout<<"调用析构函数!"<<endl; //供测试函数功能时候使用
Node<T> *p,*q;
p=first;
while(p)
{
q=p;
p=p->next;
delete q;
}
}
/*
//此为头插法:每次在头结点后边插入(链表中的内容与想象中的正好相反!)
template <class T>
LinkList<T>::LinkList(T a[],int n)
{
first=new Node<T>;
first->next=NULL;
Node<T> *p;
for(int i=0;i<n;i++)
{//初始化思想:首先新建一个节点,然后把节点一个一个连在头结点后面
p=new Node<T> ;
p->data=a[i];
p->next=first->next;
p->next=NULL;
first->next=p;
}
}*/
//尾插法:每次在链表尾部插入
template <class T>
LinkList<T>::LinkList(T a[],int n)
{
//首先建立一个只有头结点的空链表!
first=new Node<T>;
first->next=NULL;
//然后向空链表中插入新节点
Node<T> *r,*s;//定义一个尾指针与一个节点指针
r=first;
for(int i=0;i<n;i++)
{
s=new Node<T>;
s->data=a[i];
r->next=s;
r=s;
}
r->next=NULL;//一定要注意(链表建立完成,终端节点的指针域置空)
}
//求单链表的长度
template <class T>
int LinkList<T>::Length ()
{
//cout<<"********求单链表的长度********"<<endl;
//cout<<"单链表的长度为:";
Node<T> *p;
p=first;
int length=0;
while(p->next)
{
length++;
p=p->next;
}
return length;
}
//单链表按值查找
template <class T>
int LinkList<T>::Locate (T value)
{
cout<<"********单链表按值查找********"<<endl;
int location=-1;
int count=0;//计算跳过节点的个数
Node<T> *p;
//p=first->next;
for(p=first->next;p->next!=NULL;p=p->next)
{
count++;
if(p->data==value)
{
location=count;
break;
}
}
if(location==-1)
throw"查找的值不存在!";
else
return location;
}
//单链表按位置查找
template <class T>
T LinkList<T>::Get (int location)
{
cout<<"********单链表按位置查找********"<<endl;
int Len=Length();
if(location<1 || location >Len)
throw"查找位置越界!";
else
{
Node<T> *p;
p=first->next;
for(int i=0;i<location-1;i++)
p=p->next;
return p->data;
}
}
//单链表插入操作
template <class T>
void LinkList<T>::Insert (T value,int location)
{
cout<<"********单链表插入操作********"<<endl;
if(location<1 || location>Length()+2)
throw"插入位置异常!";
else
{
//首先查找到要插入的位置
Node<T> *p;
p=first;
for(int i=0;i<location-1;i++)
p=p->next;
//新建一个节点
Node<T> *s;
s=new Node<T>;
//然后将其插入到此处(注意特殊的插入位置:头部与尾部)
s->data=value;
s->next=p->next;
p->next=s;
cout<<"节点插入成功"<<endl;
}
}
//单链表删除操作
template <class T>
T LinkList<T>::Delete (int location)
{
cout<<"********单链表删除操作********"<<endl;
if(location<1 ||location >Length())
throw"删除位置越界!";
else
{
Node<T> *p;
p=first;
for(int i=0;i<location-1;i++)
p=p->next;
Node<T> *q=p->next;//暂时存待删除的节点
T value=q->data;
p->next=q->next;
delete q;
return value;
}
}
//打印单链表
template <class T>
void LinkList<T>::PrintList()
{
cout<<"********打印单链表********"<<endl;
Node<T> *p;
p=first->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void main()
{
cout<<"-----------单链表操作------------"<<endl<<endl;
LinkList <int> L1;
int a[5]={0,1,2,3,4};
LinkList <int> L2(a,5);
L2.PrintList ();
cout<<L2.Length()<<endl;
cout<<L2.Locate (1)<<endl;
try
{
cout<<L2.Locate(61)<<endl;
}
catch(char *Exception)
{
cout<<Exception<<endl;
}
cout<<L2.Get(2)<<endl;
try
{
cout<<L2.Get(8)<<endl;
}
catch(char *Exception)
{
cout<<Exception<<endl;
}
L2.Insert(20,6);
L2.PrintList();
cout<<L2.Delete(6)<<endl;
L2.PrintList();
}
#include <iostream>
using namespace std;
struct elem
{
int coef;
int exp;
elem *next;
};
class Multiple
{
private:
elem *first;
public:
Multiple();
Multiple(int a[][2],int n);
~Multiple();
void Print();
friend void Add(Multiple &M1,Multiple &M2);
};
Multiple::Multiple()
{
first=new elem;
first->next =NULL;
}
/*Multiple::Multiple(int a[][2],int n)
{
elem *p;
first=new elem;
first->next =NULL;
for(int i=0;i<n;i++)
{
p=new elem;
p->coef=a[i][0];p->exp=a[i][1];
p->next=first->next ;
first->next =p;
}
}*/
Multiple::Multiple(int a[][2],int n)
{
elem *r,*s;
first=new elem;
r=first;
for(int i=0;i<n;i++)
{
s=new elem;
s->coef =a[i][0];s->exp =a[i][1];
r->next =s;
r=s;
}
r->next =NULL;
}
Multiple::~Multiple ()
{
elem *p,*q;
p=first;
while(p)
{
q=p;
p=p->next;
delete q;
}
}
void Add(Multiple &M1,Multiple &M2)
{
cout<<"**********多项式求和***********"<<endl;
elem *p,*q;
elem *pre,*qre;
pre=M1.first ;qre=M2.first ;
p=M1.first ->next ;q=M2.first->next ;
while(p!=NULL && q!=NULL)
{
if(p->exp<q->exp)
{
pre=p;
p=p->next ;
}
else if(p->exp>q->exp )
{
elem *v;
v=q->next ;
pre->next =q;
q->next =p;
q=v;
}
else
{
p->coef =p->coef +q->coef ;
if(p->coef ==0)
{
pre->next =p->next ;
delete p;
p=pre->next ;
qre->next =q->next ;
delete q;
q=qre->next;
}
else
{
pre=p;
p=p->next;
qre->next =q->next ;
delete q;
q=qre->next;
}
}
}
if(q)pre->next =q;
//delete M2.first ;//注意这句话不能添加,因为程序中定义了析构函数!
}
void Multiple::Print ()//心得:当考虑全局是无法达到预期结果的时候,不妨考虑单独每一项
{
cout<<"**********输出多项式***********"<<endl;
elem *p;
int i=0;
p=first->next ;
while(p)
{
i++;
if(i==1)
{
if(p->exp==0)
cout<<p->coef;
else
cout<<p->coef<<"x^"<<p->exp;
}
else
{
if(p->exp==0)
cout<<"+"<<p->coef;
else
{
if(p->coef >0)
cout<<"+"<<p->coef<<"x^"<<p->exp;
else
cout<<p->coef<<"x^"<<p->exp;
}
}
p=p->next ;
}
cout<<endl;
}
void main()
{
Multiple M0;
int a[5][2]={{4,0},{3,2},{12,5},{-6,6},{7,8}};
int b[4][2]={{3,0},{1,2},{-3,3},{5,6}};
Multiple M1(a,5);Multiple M2(b,4);
M1.Print ();M2.Print();
Add(M1,M2);
M1.Print ();
}
单链表:每个节点的数据为结构体
#include <iostream>
using namespace std;
struct Student
{
char *Name;
char *Course;
float Score;
};
struct Node
{
struct Student S;
Node *next;
};
class LinkList
{
private:
Node *first;
public:
LinkList();
LinkList(struct Student a[],int n);
~LinkList();
void Print();
};
LinkList::LinkList(struct Student a[],int n)
{
Node *r,*s;
first=new Node;
r=first;
for(int i=0;i<n;i++)
{
s=new Node;
s->S.Name=a[i].Name;
s->S.Course=a[i].Course;
s->S.Score=a[i].Score;
r->next=s;
r=s;
}
r->next=NULL;
}
LinkList::~LinkList ()
{
Node *p,*q;
p=first;
while(p)
{
q=p;
p=p->next;
delete q;
}
}
void LinkList::Print()
{
Node *p;
p=first->next ;
while(p)
{
cout<<"姓名:"<<p->S.Name<<" ";
cout<<"科目:"<<p->S.Course<<" ";
cout<<"成绩:"<<p->S.Score<<endl;
cout<<"*****************************************"<<endl;
p=p->next ;
}
}
void main()
{
struct Student Stu[2]={{"Hcx","Math",100.0},{"Ysq","Englisth",100.0}};//结构体数据赋值的方法
//Stu[0].Name ="Hcx";Stu[0].Course ="Math";Stu[0].Score =100.0;
//Stu[1].Name ="Ysq";Stu[1].Course ="English";Stu[1].Score =100.0;
LinkList L1(Stu,2);
L1.Print ();
}
#include <iostream>
using namespace std;
template <class T>
struct Node
{
T *ptr;
Node<T> *next;
};
template <class T>
class LinkList
{
private:
Node<T> *first;
public:
LinkList();
LinkList(T *p[],int n);
~LinkList();
void Print();
};
template <class T>
LinkList<T>::LinkList(T *p[],int n)
{
Node <T> *r,*s;
first=new Node<T>;
r=first;
for(int i=0;i<n;i++)
{
s=new Node<T>;
s->ptr=p[i];
r->next=s;
r=s;
}
}
template <class T>
LinkList<T>::~LinkList ()
{
Node<T> *p,*q;
p=first;
while(p)
{
q=p;
p=p->next;
delete q;
}
}
template <class T>
void LinkList<T>::Print ()
{
Node<T> *p;
int count=0;
p=first;
while(p)
{
p=p->next;
count++;
if(count%20==0)
cout<<"*************************************"<<endl;
cout<<p->*ptr<<" ";//为什么此处除了问题
}
}
void main()
{
int a[1000],*p[1000];
for(int i=0;i<1000;i++)
{
a[i]=i+1;
p[i]=&a[i];
}
LinkList<int> L(p,1000);
L.Print();
}
关于循环移位:
#include <iostream>
using namespace std;
const int MaxSize=100;
class Array_Remove
{
private:
int Data[MaxSize];
int Length;
public:
Array_Remove();
Array_Remove(int a[],int n);
~Array_Remove();
void Print();
friend void Reverse(int start,int end ,Array_Remove &A);//友元函数函数没有this指针
void CirculateRemove(int i,Array_Remove &A);
};
Array_Remove::Array_Remove()
{
Length=0;
}
Array_Remove::Array_Remove(int a[],int n)
{
if(n>MaxSize)
throw"参数非法!";
for(int i=0;i<n;i++)
Data[i]=a[i];
Length=n;
}
void Array_Remove::Print ()
{
for(int i=0;i<Length;i++)
cout<<Data[i]<<" ";
cout<<endl;
}
void Reverse (int start,int end ,Array_Remove &A)
{
int Middle=(start+end)/2;
int temp;int j=0;
for(int i=start;i<=Middle;i++)
{
temp=A.Data[i];
A.Data[i]=A.Data[end-j];//友元函数没有this指针
//此处切不可写成Data[i]=Data[end-j];
A.Data[end-j]=temp;
j++;
}
}
void Array_Remove::CirculateRemove(int i,Array_Remove &A)
{
cout<<"*********循环左移*********"<<endl;
Reverse(0,i-1,A);
cout<<"Step 1:"; A.Print ();
Reverse(i,Length-1,A);
cout<<"Step 2:"; A.Print();
Reverse(0,Length-1,A);
cout<<"Step 3:"; A.Print ();
}
Array_Remove::~Array_Remove()
{
}
void main()
{
int a[10];
for(int i=0;i<10;i++)
a[i]=i;
Array_Remove A(a,10);
A.Print ();
A.CirculateRemove (5,A);
//A.Print ();
}
数据移位小程序:
#include <iostream>
using namespace std;
void Reverse(int start,int end,int t[]);
void main()
{
int a[10];
for(int i=0;i<10;i++)
a[i]=i;
//Reverse(0,4,a);
Reverse(5,9,a);
for(i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
}
void Reverse(int start,int end,int t[])
{
int Middle=(start+end)/2;
int temp;int j=0;
for(int i=start;i<Middle;i++)
{
temp=t[i];
t[i]=t[end-j];
t[end-j]=temp;
j++;
}
}
一个单链表拆成三个单链表:
#include <iostream>
using namespace std;
struct Node
{
char data;
Node *next;
};
class Classify
{
private:
Node *first;
public:
Classify(char a[],int n);
Classify();
~Classify();
int Length();
void Print();
void Sort();
};
Classify::Classify(char a[],int n)
{
first=new Node;
Node *r,*s;
r=first;
for(int i=0;i<n;i++)
{
s=new Node;s->data=a[i];
r->next =s;
r=s;
}
r->next =NULL;
}
Classify::Classify()
{
first=new Node;
first->next =NULL;
}
Classify::~Classify ()
{
Node *p,*q;
p=first;
while(p)
{
q=p;
p=p->next ;
delete q;
}
}
int Classify::Length()
{
Node *p;
p=first;int Len=0;
while(p->next)
{
p=p->next ;
Len++;
}
return Len;
}
void Classify::Print ()
{
Node *p;
p=first->next ;
while(p)
{
cout<<p->data <<" ";
p=p->next;
}
cout<<endl;
}
void Classify::Sort()
{
Node *r1,*s1;
Node *first1=new Node;r1=first1;
Node *r2,*s2;
Node *first2=new Node;r2=first2;
Node *r3,*s3;
Node *first3=new Node;r3=first3;
Node *p;
p=first;
for(int i=0;i<Length();i++)
{
p=p->next ;
if((p->data >='A' &&p->data<='Z' )||(p->data >='a' && p->data <='z'))
{
s1=new Node; s1->data =p->data ;
r1->next =s1;
r1=s1;
}
else if((p->data -'0')>=0 && (p->data -'0')<=9)
{
s2=new Node; s2->data =p->data ;
r2->next =s2;
r2=s2;
}
else
{
s3=new Node; s3->data =p->data ;
r3->next =s3;
r3=s3;
}
r1->next =NULL;
r2->next =NULL;
r3->next =NULL;
}
cout<<"打印链表一:";
Node *p1;
p1=first1->next ;
while(p1)
{
cout<<p1->data <<" ";
p1=p1->next;
}
cout<<endl;
cout<<"打印链表二:";
Node *p2;
p2=first2->next ;
while(p2)
{
cout<<p2->data <<" ";
p2=p2->next;
}
cout<<endl;
cout<<"打印链表三:";
Node *p3;
p3=first3->next ;
while(p3)
{
cout<<p3->data <<" ";
p3=p3->next;
}
cout<<endl;
}
void main()
{
char *a="1a2b3c4d5e6f7g8h*7$a>9k|+-a";
int n=strlen(a);
Classify A(a,n);
A.Print ();
A.Sort ();
}
约瑟夫环问题
#include <iostream>
using namespace std;
struct Node
{
int num;
Node *next;
};
class Jose
{
private:
Node *first;
public:
Jose(int n);
~Jose();
Jose();
int Length();
void Print();
void Jose_Del(int m);
};
Jose::Jose()
{
first =new Node ;
first->next=first;
}
Jose::Jose(int n)
{
Node *r,*s;
first=new Node;
r=first;
for(int i=0;i<n;i++)
{
s=new Node;
s->num =i+1;
r->next =s;
r=s;
}
r->next =first;
}
Jose::~Jose ()
{
Node *p,*q;
p=first->next ;
while(p!=first)
{
q=p;
p=p->next ;
delete q;
}
}
int Jose::Length()
{
int len=0;
Node *p;
p=first->next ;
while(p!=first)
{
len++;
p=p->next ;
}
return len;
}
void Jose::Jose_Del (int m)
{
cout<<"^^^^^^^^^^输出约瑟夫环出环顺序:"<<endl;
if(m==1)//注意特殊情形
this->Print ();
else
{
Node *p,*pre;
pre =first;
p=first->next ;
int count=0;
int endFlag=0;
int Del_data=0;
int flag=this->Length();
while(1)
{
if(p!=first)
count++;
if(count==m )
{
Del_data=p->num ;
cout<<Del_data<<" ";
pre->next =p->next ;
delete p;
p=pre->next ;
//注意此处count如何再次初始化
endFlag++;
if(endFlag%10==0)
cout<<endl;
if(p!=first)
count=1;
else
count=0;
}
if(endFlag==flag )
break;
pre=p;
p=p->next;
}
}
}
void Jose::Print ()
{
cout<<"^^^^^^^^^原始约瑟夫环:"<<endl;
Node *p;
int count=0;
p=first->next ;
while(p!=first)
{
count++;
cout<<p->num <<" ";
p=p->next ;
if(count%10==0)
cout<<endl;
}
cout<<endl;
}
void main()
{
cout<<"*************约瑟夫环问题*************"<<endl;
int n,m;
cout<<"输入初始总人数:";
cin>>n;
cout<<"输入淘汰标志数:";
cin>>m;
Jose S1(n);
S1.Print ();
S1.Jose_Del (m);
cout<<endl;
}