文章目录
一、链表
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
1.1 什么是链表
链表是一种物理上非连续、非顺序的存储结构, 数据的逻辑顺序通过链表中的指针链接次序实现
1.2 相关概念
链表中的元素称为结点。每一个结点都包含两类 数据:
- 一类数据称为结点的值域;
- 另一类数据称 为链域,它是与结点同类型的指针。
结点类型定义:
struct node { int data; node *next; };
node *p1,*p2;
1.3 结点数据的访问形式
设指针 p 指向某结点,可用p访问该结点
- 数据域:(*p).data 或 p->data
- 指针域:(*p).next 或 p->next
1.4 创建一条无序链表
(1)置头指针 head = 0;
(2)输入一个数据,如果该数据有效,则转步骤(3), 否则转步骤(5);
(3)申请分配一个结点空间,并把该空间的地址存入指针变量p中,然后把输入的数据存入该结点;
(4)若当前链表为空,即head为0,则直接把p赋给 head, 否则接入链表末尾。转步骤(2);
(5)如果head不为0,则置尾结点的指针域为0;
(6)返回头指针head的值,程序结束
1.5 遍历输出链表各结点的值。
void Print(const node *head) {
const node *p; p = head;
while(p!=0) {
cout<data<<'\t’;
p=p->next;
}
cout<<endl;
}
1.6 删除链表上具有特定值的一个结点
(1)若head为0,则转步骤(6);
(2)如果第一个结点即为要找的结点,则转步骤 (5);
(3)检查下一结点P;
(4)若P不存在,则转步骤(6),若P为要找的结点,则转 步骤(5),否则转步骤(3);
(5)从链表中删除该结点;
(6)返回头指针,算法结束
1.7 释放链表的结点空间
void deletechain(node *head) {
node *p1;
while(head) {
p1 = head;
head = head->next;
delete p1;
}
}
1.8 把一个结点插入升序链表
node *Insert(node *head,node *p) {
node *p1,*p2;
if(head == 0 ) {
head = p;
p->next = 0;
return head;
}
if(head->data >= p->data) {
p->next = head;
head = p;
return head;
}
p2 = p1 = head;
while(p2->next && p2->data < p->data) {
p1 = p2;
p2 = p2->next;
}
if(p2->data < p->data) {
p2->next = p;
p->next = 0;
}
else {
p->next = p2;
p1->next = p;
}
return head;
}
1.9 建立一条有序链表
node *Create_sort(void) {
node *p1,*head = NULL;
int a;
cout<<”产生一条有序链表,输入数据,以-1结束:\n”;
cin>>a;
while(a!=-1) {
p1 = new node;
p1->data=a;
head = Insert(head,p1);
cin>>a;
}
return head;
}
二. 面向对象的程序设计语言——C++
2.1 设计方法概述
•是建立在“对象”及其相关概念基础上的程序设计方法学。
• 它在分析问题的构成及其各部分相互联系的基础上,通过 一组数据抽象,把问题分解成一个个的对象来对问题建模;
• 然后以对象为中心,以类、继承和多态机制来认识、理解、 刻画客观世界,并设计、构建相应的程序。
• 算法和数据被封装在类中,程序的功能通过类的对象实例 之间的相互作用表现出来。
2.2 有关概念
- 1.对象:
由属和行为构成,C++中,分别体现为数据以及函数 - 2.封装及信息隐蔽
(1)对象的封装,各个对象相互独立,互不干扰
(2)对象中某些部分的隐藏,只留下少量接口 - 3.抽象
把具有同一性质的对象归到一类 - 4.继承与重用
在类A的基础上增加一些新内容得到类B,则A(父类/基类),B(子类/派生类) - 5.多态
不同派生类的对象对于同一消息作出不同的反应
2.3 举例
2.4 类和对象的定义及引用
2.4.1 类的定义
类的定义一般包括两个部分:声明部分和实现部分。
Class<类名> {
public:
<数据成员或成员函数的声明>
protected:
<数据成员或成员函数的声明>
private:
<数据成员或成员函数的声明>
};
- 类的实现主要是指类的成员函数的定义;
- 类的成员函数定义可在类体外进行,也可在类体内进行;
- 类定义中声明的数据成员和成员函数都具有类作用域;
- 在类体外定义成员函数时,需用类名加域运算符“::”进行限定;
2.4.2 对象的定义
- 对象是类类型的变量,是类的实例;
- 通过定义对象、为对象分配空间、让对 象之间相互作用 来实现程序的功能;
- 对象与普通变量的作用域规则相同。
2.5 构造函数
2.5.1 构造函数的提出
- 构造函数在对象被创建时使用特定的值构造对象,或者 说将对象初始化为一个特定的状态。
- 构造函数是类中一个特殊的成员函数,其语法形式为:
ClassName(形参表)
{ … }
或者
ClassName::ClassName(形参表)
{ … }
例程:
class Time {
public:Time( ); //构造函数
void SetTime(int newH, int newM, int newS) {
hour= newH;
minute= newM;
second= newS;
}
void ShowTime() {
cout<<hour<<"\t"<<minute<<"\t"<<second<<"\n";
}
private: int hour, minute, second;
}
Time::Time( ) {
hour= 1;
minute= 2;
second= 3;
}
int main() {
Time c;
Time c( );
// c. Time( );
c.ShowTime();
return 0;
}
2.5.2 构造函数的特性
- ① 构造函数的函数名必须与类名相同
- ② 不能指定构造函数返回值的类型
- ③ 构造函数可以重载
- ④ 构造函数由系统调用
- ⑤ 构造函数一般是公有的或保护的成员函数
- ⑥ 若没有定义构造函数,系统会提供一个默认构造函数
2.6 带参数的构造函数
例程:
class Rectangle {
private: int left , top , right , bottom ; public: Rectangle(int l, int t, int r,int b) {
left=l ; top=t ; right=r ; bottom=b; cout<< "调用带参构造函数!\n";
}
Rectangle() {
left=0 ; top=0 ; right=0 ; bottom=0 ;
cout<< "调用不带参构造函数!\n ";
}
void print() {
cout<<left<<" "<<top<<" " ; cout<<right<<" "<<bottom<<'\n’;
}
};
int main() {
Rectangle r1(100,200,300,400);
r1.print();
Rectangle r2;
Rectangle r3();
r2.print();
return 0;
}
2.7 析构函数
2.7.1 析构函数的提出
-
析构函数完成对象被删除前( 释放对象占用空间前)的一些清理工作。
-
析构函数的语法形式为:
~ClassName( ) { … }
或者
ClassName::~ClassName( )
例程:
class Q {
int x,y;
public: Q(int a=0,int b=0) {
x = a;
y = b;
}
~Q() {
cout<<"调用了析构函数!\n";
}
void P(void) {
cout<<x<<'\t'<<y<<endl;
}
};
int main() {
Q q(50,100);
q.P();
cout<< "退出主函数¡\n";
return 0;
}
2.7.2 析构函数的特性
- ① 析造函数的函数名与类名相同,并在前加字符”~”
- ② 析造函数不能带有任何参数,无返回值类型
- ③ 析造函数一般在撤销对象时由系统隐式调用
- ④ 析造函数一般是公有的或保护的成员函数
- ⑤ 若没有定义析造函数,系统会提供默认析造函数
- ⑥ 析构函数中不能包含exit函数
2.8 对象成员
2.8.1 对象成员的初始化
- 创建对象时首先对其包含的对象成员初始化;
- 使用构造函数初始化表对对象成员初始化。
2.8.2 对象成员的引用
- 通过对象名(或对象的引用)和成员运算符引用对象中的成员
对象名. 成员名 - 通过指向对象的指针引用对象中的成员
指针变量->成员名
2.9 类的继承
2.9.1 包含——复用类的实现
class Engine {
public: void fire(void)
{ … }//点火
void stall(void)
{ … }//熄火
……
};
class Car {
Engine engine;
public: void run()
{ engine.fire(); //… }
void stop()
{ engine.stall(); //… }
};
int main() {
Car benz;
benz.run();
benz.stop();
}
2.9.2 单一继承
- Class<派生类名> :基类名 { … }; //类体
- 三种继承(派生)方式
- 公有继承(派生)
- 私有继承(派生)
- 保护继承(派生)
- 不同继承方式的影响主要体现在: 通过派生类对象对基类成员的访问权限
2.9.2.1 公有继承
- 基类的所有成员在派生类中保持各个成员的访问权限 不变;
- 派生类中的成员函数可以直接访问基类中的public和 protected成员,但不能直接访问基类的private成员;
- 公有派生类继承了基类的接口,能够发送给基类对象 的消息派生类对象也可以接收。
例程:
class A {
int x;
protected: int y;
public: int z;
A(int a,int b,int c) {
x=a;y=b;z=c;
}
int Getx( ) { return x; }
int Gety( ) { return y; }
void ShowA( ) {
cout<<x<<'\t' <<y<<'\t'<<z;
}
};
class B:public A {
int Length,Width;
public: B(int a,int b,int c,int d,int e):A(a,b,c) {
Length=d;Width=e;
}
void ShowB() {
cout<<Length<<'\t'<<Width<<'\n';
cout<<Getx()<<'\t'<<y<<'\t'<<< "Sum="<<b1.Sum()<<'\n';
cout << "y=" <<b1.Gety()<<'\t';
cout << "z="<<b1.z<<'\n’;
}
};
2.9.2.2 私有继承
- 基类的所有成员在派生类中的访问权限全部变为私有;
- 派生类中的成员函数可以直接访问基类中的public和 protected成员,但不能直接访问基类的private成员;
- 派生类的用户不能访问基类的数据和功能。
例程:
class A {
int x;
protected:int y;
public:int z;
A(int a,int b,int c) {
x=a;y=b;z=c;
}
int Getx() { return x; }
int Gety() { return y; }
void ShowA() {
cout<<x<<'\t‘<<y<<'\t‘<<z;
}
};
class B:private A {
int Length,Width;
public: B(int a,int b,int c,int d,int e):Base(a,b,c) {Length=d;Width=e;}
void ShowB() {
cout<<Length<<'\t’<<Width<<'\n';
cout<<Getx()<<'\t‘<<y<<'\t‘<<z<<'\n‘;
}
int Sum(void) {
return (Getx()+y+z+Length+Width);
}
};
void main(void) { B b1(1,2,3,4,5); b1.ShowA(); X错误
cout<<"Sum="<<b1.Sum()<<'\n’;
cout << "y=" <<b1.Gety()<<'\t'; X错误
cout << "z="<<b1.z<<'\n’; X错误
}
2.9.2.3 保护继承
- 基类中的公有成员和保护成员在派生类中均变 为保护成员,它们仍然可被它的子类所继承。
- 派生类中的成员函数可以直接访问基类中的 public和protected成员,但不能直接访问基类 的private成员。
- 通过派生类的对象不能直接访问基类中的任何成员。
例程:
class A {
protected: int x;
};
int main() {
A a;
a.x=5; ×
}
class A {
protected: int x;
}
class B: protected A {
public: void Function() { x=5;}
};
三. Java环境配置
3.1 Java的历史
有兴趣的自己看百度百科吧> 链接地址