Skip to content

Commit 1683bca

Browse files
committed
update
1 parent 4ae668c commit 1683bca

File tree

7 files changed

+438
-316
lines changed

7 files changed

+438
-316
lines changed

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
- 出栈(Pop):将栈顶的数据弹出的操作。先取出栈顶指针所指位置的数据,再通过 修改栈顶引用,使其指向栈中的下一个元素。
1616

1717
## 队列结构
18+
从数据的逻辑结构来看,队列是一种线性结构。如果从数据的存储结构来进一步划分,队列结构包括两类。
19+
- [顺序队列结构](./src/dataStructure/queue):即使用一组地址连续的内存单元依次保存队列中的数据。在程序中,可以定义一个指定大小的结构数组作为队列。
20+
- 链式队列结构:即使用链表形式保存队列中各元素的值。
21+
22+
从数据的运算角度来分析,队列结构是按照“先进先出”的原则处理结点数据的。在队列结构中,数据运算非常简单。一般队列结构的基本操作只有
23+
- 入队列:将一个元素添加到队尾(相当于到队列最后排队等候)
24+
- 出队列:将队头的元素取出,同时删除该元素,使后一个元素成为队头。
1825

1926
## 数结构
2027

src/dataStructure/linkedList/README.md

+114-108
Original file line numberDiff line numberDiff line change
@@ -14,158 +14,164 @@
1414

1515
## 准备数据
1616
准备在 链表操作中需要用到的变量及类。
17+
```java
18+
class DATA{
19+
String key; // 结点的关键字
20+
String name;
21+
int age;
22+
}
1723

18-
class DATA{
19-
String key; // 结点的关键字
20-
String name;
21-
int age;
22-
}
23-
24-
/*
25-
* 定义链表结构
26-
* Chain-type storage structure
27-
*/
28-
class CLType{
29-
DATA nodeData = new DATA();
30-
CLType nextNode;
31-
}
24+
/*
25+
* 定义链表结构
26+
* Chain-type storage structure
27+
*/
28+
class CLType{
29+
DATA nodeData = new DATA();
30+
CLType nextNode;
31+
}
32+
```
3233
上述代码定义了链表数据元素的类DATA及链表的类CLType。结点的具体数据保存在一个类DATA中,而引用nextNode用来指向下一个结点。
3334

3435
其实可以认为该链表是一个班级学生的记录,和上面顺序表所完成的工作类似。
3536
## 追加结点
3637
追加结点即在链表末尾增加一个结点。表尾结点的地址部分原来保存的是空地址null,此时需要将其设置为新增加结点的地址(即原表尾结点指向新增结点),然后将新增结点的地址部分设置为空地址null,即新增节点成为表尾
3738

3839
由于一般情况下,链表只有一个头引用head,要在末尾添加结点就需要从头引用head开始逐个检查,直到找到最后一个结点(即表尾)。
39-
40-
CLType CLAddEnd(CLType head, DATA nodeData){
41-
CLType node,htemp;
42-
if((node=new CLType())==null){
43-
System.out.println("申请内存失败!\n");
44-
return null;
45-
}else{
46-
node.nodeData = nodeData; // 在新申请的结点中保存数据
47-
node.nextNode = null; // 设置结点引用为空,即为表尾
48-
if(head == null){ // 当head为空时,加入的新结点即为头引用
49-
head = node;
50-
return head;
51-
}
52-
htemp = head;
53-
while(htemp.nextNode != null){ // 查找链表的末尾
54-
htemp = htemp.nextNode;
55-
}
56-
htemp.nextNode = node; // 在链表的末尾插入该结点
57-
return head; // 返回指代整个链表的头引用
40+
```java
41+
CLType CLAddEnd(CLType head, DATA nodeData){
42+
CLType node,htemp;
43+
if((node=new CLType())==null){
44+
System.out.println("申请内存失败!\n");
45+
return null;
46+
}else{
47+
node.nodeData = nodeData; // 在新申请的结点中保存数据
48+
node.nextNode = null; // 设置结点引用为空,即为表尾
49+
if(head == null){ // 当head为空时,加入的新结点即为头引用
50+
head = node;
51+
return head;
5852
}
53+
htemp = head;
54+
while(htemp.nextNode != null){ // 查找链表的末尾
55+
htemp = htemp.nextNode;
56+
}
57+
htemp.nextNode = node; // 在链表的末尾插入该结点
58+
return head; // 返回指代整个链表的头引用
5959
}
60+
}
61+
```
6062
在上述代码中,输入参数head为链表头引用,输入参数nodeData为结点保存的数据。程序中,使用new关键字申请保存结点数据的内存空间,如果分配内存成功,node中将保存指向该内存区域的引用。然后,将传入的nodeData保存到申请的内存区域,并设置该结点指向下一结点的引用值为null,最后将该结点链接到链表的末尾。
6163
## 插入头结点
6264
插入头结点即在链表的首部添加结点的过程。
6365
步骤如下:
6466
1. 分配内存空间,保存新增的结点。
6567
- 使新增结点指向头引用head所指向的结点。
6668
- 使头引用head指向新增结点。
67-
68-
CLType CLAddFirst(CLType head, DATA nodeData){
69-
CLType node;
70-
if((node = new CLType())==null){
71-
System.out.println("申请内存失败!\n");
72-
return null;
73-
}else{
74-
node.nodeData = nodeData; // 保存数据
75-
node.nextNode = head; // 新加入的头结点的nextNode指向头引用所指的结点
76-
head = node; // 头引用指向新节点
77-
return head;
78-
}
69+
```java
70+
CLType CLAddFirst(CLType head, DATA nodeData){
71+
CLType node;
72+
if((node = new CLType())==null){
73+
System.out.println("申请内存失败!\n");
74+
return null;
75+
}else{
76+
node.nodeData = nodeData; // 保存数据
77+
node.nextNode = head; // 新加入的头结点的nextNode指向头引用所指的结点
78+
head = node; // 头引用指向新节点
79+
return head;
7980
}
80-
81+
}
82+
```
8183
## 查找结点
8284
通过关键字进行查询。
83-
84-
CLType CLFindNode(CLType head, String key){
85-
CLType htemp;
86-
htemp = head;
87-
while(htemp!=null){ // 循环遍历,寻找关键字匹配的结点
88-
if(htemp.nodeData.key.compareTo(key)==0){
89-
return htemp;
90-
}
91-
htemp = htemp.nextNode;
85+
```java
86+
CLType CLFindNode(CLType head, String key){
87+
CLType htemp;
88+
htemp = head;
89+
while(htemp!=null){ // 循环遍历,寻找关键字匹配的结点
90+
if(htemp.nodeData.key.compareTo(key)==0){
91+
return htemp;
9292
}
93-
return null;
93+
htemp = htemp.nextNode;
9494
}
95+
return null;
96+
}
97+
```
9598
在上述代码中,输入参数head为链表的头引用,输入参数key是用来在链表中进行查找结点的关键字。程序中,首先从链表头引用开始,对结点进行逐个比较,直到查找到。找到关键字相同的结点后,返回该结点的引用,方便调用程序处理。
9699
## 插入结点
97100
插入结点就是在链表中间部分的指定位置增加一个结点。插入结点的操作步骤如下:
98101
1. 分配内存空间,保存新增的结点。
99102
- 找到要插入的逻辑位置,也就是那两个结点之间。
100103
- 使新增节点指向原插入位置所指向的结点,并修改插入位置结点的引用,使其指向新增结点。
101-
102-
CLType CLInsertNode(CLType head, String findKey, DATA nodeData){ // 插入关键字结点
103-
CLType node, nodetemp;
104-
if((node = new CLType())==null){
105-
System.out.println("申请内存失败!\n");
106-
return null;
107-
}
108-
node.nodeData = nodeData;
109-
nodetemp = CLFindNode(head, findKey); // 获取插入位置关键字所指代的结点
110-
if(nodetemp == null){
111-
System.out.println("未找到正确的插入位置!\n");
112-
}else{
113-
node.nextNode = nodetemp.nextNode; // 新插入的节点的nextNode指向关键字结点的下一结点
114-
nodetemp.nextNode = node; // 设置关键结点指向新插入结点
115-
}
116-
return head;
104+
```java
105+
CLType CLInsertNode(CLType head, String findKey, DATA nodeData){ // 插入关键字结点
106+
CLType node, nodetemp;
107+
if((node = new CLType())==null){
108+
System.out.println("申请内存失败!\n");
109+
return null;
117110
}
111+
node.nodeData = nodeData;
112+
nodetemp = CLFindNode(head, findKey); // 获取插入位置关键字所指代的结点
113+
if(nodetemp == null){
114+
System.out.println("未找到正确的插入位置!\n");
115+
}else{
116+
node.nextNode = nodetemp.nextNode; // 新插入的节点的nextNode指向关键字结点的下一结点
117+
nodetemp.nextNode = node; // 设置关键结点指向新插入结点
118+
}
119+
return head;
120+
}
121+
```
118122
## 删除结点
119123
删除结点就是将链表中的某个结点数据删除。删除结点的操作步骤如下:
120124
1. 查找需要删除的结点。
121125
- 使前一结点指向当前结点的下一结点。
122126
- 删除结点。
123-
124-
int CLDeleteNode(CLType head, String key){ // 删除关键字结点
125-
CLType htemp,tempnode;
126-
if(head == null){
127-
return 0;
128-
}
129-
htemp = head;
130-
tempnode = head;
131-
while(htemp != null){
132-
if(htemp.nodeData.key.compareTo(key)==0){ // 遍历查找
133-
tempnode.nextNode = htemp.nextNode; // 当前结点的引用指向下一个结点的引用,以此删除htemp结点
134-
return 1;
135-
}
136-
tempnode = htemp; // 保存当前结点
137-
htemp = htemp.nextNode; // 指向下一个结点
138-
}
127+
```java
128+
int CLDeleteNode(CLType head, String key){ // 删除关键字结点
129+
CLType htemp,tempnode;
130+
if(head == null){
139131
return 0;
140132
}
133+
htemp = head;
134+
tempnode = head;
135+
while(htemp != null){
136+
if(htemp.nodeData.key.compareTo(key)==0){ // 遍历查找
137+
tempnode.nextNode = htemp.nextNode; // 当前结点的引用指向下一个结点的引用,以此删除htemp结点
138+
return 1;
139+
}
140+
tempnode = htemp; // 保存当前结点
141+
htemp = htemp.nextNode; // 指向下一个结点
142+
}
143+
return 0;
144+
}
145+
```
141146
注意,此时被删除结点仍然保存在内存中,接着执行赋值null操作,用来释放被删除节点所占用的内存空间。
142147
## 计算链表长度
143148
统计链表结构中结点的数量,由于链表结构在物理上不是连续存储的,因此,需要遍历整个链表来对结点数量进行累加。
144-
145-
int CLLength(CLType head){ //返回结点总数
146-
CLType htemp;
147-
int len = 0;
148-
htemp = head;
149-
while(htemp!=null){ // 循环遍历累计总结点数
150-
len++;
151-
htemp=htemp.nextNode;
152-
}
153-
return len;
149+
```java
150+
int CLLength(CLType head){ //返回结点总数
151+
CLType htemp;
152+
int len = 0;
153+
htemp = head;
154+
while(htemp!=null){ // 循环遍历累计总结点数
155+
len++;
156+
htemp=htemp.nextNode;
154157
}
158+
return len;
159+
}
160+
```
155161
程序中通过while循环来遍历整个链表,从而累加数量并返回。
156162

157163
## 显示所有结点
158-
159-
void CLAllNode(CLType head){ // 遍历链表输出所有数据
160-
CLType htemp;
161-
htemp = head;
162-
System.out.printf("\n当前链表共有%d个结点。链表所有数据如下:\n",CLLength(head));
163-
while(htemp != null){
164-
System.out.printf("结点(%s,%s,%d)\n",htemp.nodeData.key, htemp.nodeData.name, htemp.nodeData.age);
165-
htemp = htemp.nextNode;
166-
}
164+
```java
165+
void CLAllNode(CLType head){ // 遍历链表输出所有数据
166+
CLType htemp;
167+
htemp = head;
168+
System.out.printf("\n当前链表共有%d个结点。链表所有数据如下:\n",CLLength(head));
169+
while(htemp != null){
170+
System.out.printf("结点(%s,%s,%d)\n",htemp.nodeData.key, htemp.nodeData.name, htemp.nodeData.age);
171+
htemp = htemp.nextNode;
167172
}
168-
173+
}
174+
```
169175
## 链表操作实例
170176
完整实例源码:
171177
[LinkedList.java](./LinkedList.java)

0 commit comments

Comments
 (0)