数据结构草草学过,不过没有认真运用过。 虽然知道一些最为基本的抽象类型及一些常用操作,不过叫我把这些基本的算法写出来我也是写不出来的。因为常说数据结构+算法是一个程序员最基本的素质,所以这次认真加以复习。在复习的同时我尽量将自己学习的其他的一些基本知识比如C++中的面向对象思想也引入进来,同时也会将在复习中碰到其他的一些问题提出来,能解决的便解决,不能解决的可以试着解决。
To be a programmer .
----------------------------------------------------------------------------------------------------------------
线性表是由 n (n >= 0) 个类型相同的数据元素a1, a2, a3, …, an 组成的有限序列,记作(a1, a2, … , ai-1, ai, ai+1, …, an)。这里的数据元素 ai(1<=i<=n)只是一个抽象的符号,其具体的含义在不同情况下可以不同,它即可以是原子类型,也可以是结构类型,但同一线性表中的数据元素必须属于同一数据对象。
线性表有两种基本的存储结构:顺序存储结构和链式存储结构。本文档只涉及顺序存储结构,顺序结构通常可用高级程序设计语言中的数组来表示。另外文章的组织结构分为三部分:开头是简单的介绍,之后是数据结构基本运算的代码,最后是在复习中遇到的一些问题。
以下代码实现了一些线性表最基本的运算,相比书上的程序例子,自己新增了三点,有些写法是从参考别人的程序而得来的:
1) 运用了C++中的类模版概念;
2) 加入了C++中的异常捕获;
3) 规范了程序的写法,每个函数有了更为详细的介绍信息。
实现代码分三个部分:seqlist.h定义顺序表模版类,seqlist.cpp是对模版类的基本实现,main.cpp 是用于基本的测试。
----------------------------------------------------------------------------------------------------------------
- //seqlist.h
- #ifndef _SEQLIST_H_
- #define _SEQLIST_H_
- const int MAX_SIZE = 100;
- template <class T>
- class SeqList
- {
- public:
- SeqList();
- SeqList(T a[], int n);
- ~SeqList();
- int Length();
- T Get(int i);
- int Locate(T x);
- void Insert(int i, T x);
- T Delete(int i);
- void PrintList();
- private:
- T data[MAX_SIZE];
- int length;
- };
- #endif
- //seqlist.cpp
- #include <iostream>
- #include "seqlist.h"
- /*
- * pre condition: the seqlist is not exist.
- * input: no
- * purpose: to construct a seqlist.
- * output: no
- * for condition: created a seqlist.
- */
- template <class T>
- SeqList<T>::SeqList()
- {
- length = 0;
- }
- /*
- * pre condition: the seqlist is not exist.
- * input: one array containing n elements.
- * purpose: to construct a seqlist use the array.
- * output: no
- * for condition: created a seqlist.
- */
- template <class T>
- SeqList<T>::SeqList(T a[], int n)
- {
- if (n>MAX_SIZE) throw "invalid arguments";
- for (int i=0; i<n; i++)
- data[i] = a[i];
- length = n;
- }
- /*
- * pre condition: no
- * input: no
- * purpose: no
- * output: no
- * for condition: no
- */
- template <class T>
- SeqList<T>::~SeqList()
- {
- }
- /*
- * pre condition: the seqlist is existed.
- * input: the insert element 'x', insert position 'i'.
- * purpose: insert the element 'x' into the position 'i'.
- * output: no
- * for condition: the seqlist inserted the new element.
- */
- template <class T>
- void SeqList<T>::Insert(int i, T x)
- {
- int j;
- if (length >= MAX_SIZE)
- throw "overflow";
- if (i<0 || i>length)
- throw "invalid position";
- for (j=length; j>=i; j--)
- data[j] = data[j-1];
- data[i] = x;
- length ++;
- }
- /*
- * pre condition: the seqlist is existed.
- * input: the position of the element to be deleted.
- * purpose: delete the element 'x' in the position 'i'.
- * output: no
- * for condition: the seqlist deleted the new element.
- */
- template <class T>
- T SeqList<T>::Delete(int i)
- {
- T x;
- if (length == 0)
- throw "downflow";
- if (i<1 || i>length)
- throw "invalid position";
- x = data[i-1];
- for (int j=i; j<length; j++)
- data[j-1] = data[j];
- length --;
- return x;
- }
- /*
- * pre condition: the seqlist is existed.
- * input: no
- * purpose: return the number of the seqlist.
- * output: no
- * for condition: no
- */
- template <class T>
- int SeqList<T>::Length()
- {
- return length;
- }
- /*
- * pre condition: the seqlist is existed.
- * input: the index of a element.
- * purpose: return the value of the element.
- * output: the value of a element.
- * for condition: no
- */
- template <class T>
- T SeqList<T>::Get(int i)
- {
- if (i<1 || i>length)
- throw "invalid index.";
- return data[i-1];
- }
- /*
- * pre condition: the seqlist is existed.
- * input: the value wanted to be located.
- * purpose: return the index of the element.
- * output: no
- * for condition: no
- */
- template <class T>
- int SeqList<T>::Locate(T x)
- {
- for(int i=0; i<length; i++)
- {
- if (data[i] == x)
- return i;
- }
- return -1;
- }
- /*
- * pre condition: the seqlist is existed.
- * input: no
- * purpose: print all the element in the list.
- * output: no
- * for condition: no
- */
- template <class T>
- void SeqList<T>::PrintList()
- {
- std::cout <<" all the elems in the seqlist are:/n";
- for(int i=0; i<length; i++)
- std::cout <<data[i] <<" ";
- std::cout <<std::endl;
- }
- //main.cpp
- #include <iostream>
- #include "seqlist.cpp"
- int main()
- {
- try{
- /* the first test!
- * construct one empty seqlist and do something about it.
- */
- SeqList<float> seqlist;
- for(int i=0; i<5; i++)
- seqlist.Insert(i, 2.2 + i);
- seqlist.PrintList();
- std::cout <<"the length is: " <<seqlist.Length();
- std::cout <<std::endl;
- // do deletion
- seqlist.Delete(1);
- seqlist.PrintList();
- // getting end locating the elem
- std::cout << "the 2th elem is: " <<seqlist.Get(2) <<"/n";
- std::cout << "the 3.2 elem position: " <<seqlist.Locate(3.2) <<"/n";
- // do insertion
- seqlist.Insert(3, 111.1);
- seqlist.PrintList();
- /* the second test !
- * construct seqlist through one existing array.
- */
- int base[6] = { 2, 3, 4, 5, 6, 7};
- SeqList<int> seqlist_a(base, 6);
- seqlist_a.PrintList();
- std::cout <<"the length is:" <<seqlist_a.Length();
- std::cout <<std::endl;
- // getting and locating the elem
- std::cout << "the 1st elem: "<<seqlist_a.Get(1) <<"/n";
- std::cout << "the 5 positin: " <<seqlist_a.Locate(5)<<"/n";
- // do deletion
- seqlist_a.Delete(2);
- seqlist_a.PrintList();
- // do insertion
- seqlist_a.Insert(3, 222);
- seqlist_a.PrintList();
- }
- catch(const char *err)
- {
- std::cout <<err;
- }
- return 1;
- }
----------------------------------------------------------------------------------------------------------------
因为自己在决定复习数据结构的同时也复习下一些Linux的基本操作(学过,但是忘得也快),所以自己装了一个红帽的虚拟机(VMware),并通过SSH客户端来与虚拟系统进行文件传输操作。在对顺序表进行实现的过程中主要碰到三个问题:
1)什么是SSH(Secure Shell)?
我学会用这个东西时是在老师的介绍之下,之后也就知道了有这么一个工具可以完成与虚拟系统进行文件的传输工作,不需要每次很麻烦的去装VMware tools 或者设置所谓的共享目录了,不过对于它是一个什么东西了解得不多。
我们所熟悉的SSH通常是指的一种基于SSH协议的、通用的、功能强大的网络安全解决方案。一般的Unix系统、Linux系统都附带有支持SSH的应用程序包。SSH最主要的功能便是支持安全的网络数据传输。在具体的应用上,SSH是可以替代Telnet及FTP的。
因为在虚拟系统中已经有了支持SSH的应用程序包,所以我们便可以通过一个相对的客户端程序与之进行连接并实现数据传输。
2)在VMware的网络连接设置方式上,有桥接、NAT、Host-only三种不同的连接方式,它们有什么区别,在通过SSH Client进行连接的时候需要怎么进行设置?
桥接模式下,虚拟出来的操作系统与宿主主机的关系就像(局域网)是连接在同一个Hub上的两台主机,这是你需要为虚拟系统配置IP及Netmask,并且俩系统还需处于同一网段,这样俩系统便可进行通信。并且,虚拟系统可以访问局域网内任意一台主机。如果想利用VMWare在局域网内新建一个虚拟服务器,为局域网用户提供网络服务,就应该选择桥接模式。
Host-only模式下,虚拟系统的IP等配置均有VMnet1(host-only)虚拟网络的DHCP服务器来动态分配的。如果想用VMWare创建一个与网内其他机器相隔离的虚拟系统,可以选择此种模式。
NAT模式下,虚拟系统借助NAT功能,通过宿主主机所在的网络来访问公网。这种模式下的IP信息时通过VMnet8(NAT)虚拟网络的DHCP服务器提供的。无法修改,因此虚拟系统无法和本局域网中的其他真实主机进行通信。
所以在设置SSH Client的时候,可以选择【桥接模式】或者【Host-only】模式,在【桥接模式】下,只需要保证虚拟系统的IP地址与主机的IP地址处于同一个网段即可进行通信。在【Host-only模式】下,必须要保证虚拟系统的IP地址与在本机上所虚拟出来的网卡的IP地址(VMware Network Adapter VMnet1)处在同一网段。
3)在用GCC进行编译的时候便出现错误提示,但是用G++进行编译却没有错误提示,很显然,两个编译器是有所差别的?
GCC最初的全称为 ‘GNU C Compiler’,之后随着高级程序设计语言的增多,GCC的全称逐渐演变为了’GNU Compiler Collection’。
对于G++来说,它会将被编译的文件都当作C++文件来看待,并且它会自动调用C++的标准库。
对于GCC来说,它会根据源文件的后缀名将它们区分开来,但是有一点不同的是GCC在编译C++源程序时并不会主动链接相关的库,所以需要额外指定参数。如如:gcc -lstdc++ testCpp.cpp -o testCpp。