Skip to content

Commit 2ffffaa

Browse files
authored
Create 1.Vector.md
1 parent a9df0ad commit 2ffffaa

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

造轮子/1.Vector.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Vector实现
2+
[在编程大学中第一个需要自己动手实现的数据结构就是动态数组。](https://github.com/jwasham/coding-interview-university/blob/main/README.md#arrays)
3+
4+
在实现这个数据结构时,我认为最有价值的就是remove函数的算法思想,所以下面将对它的思想进行解释。
5+
## remove的一种优雅算法
6+
**函数声明**
7+
8+
remove(T target)
9+
10+
(我为数组实现了泛型,所以target的数据类型是任意的。)
11+
12+
**函数要求**
13+
14+
输入一个目标数target,要求删除数组中所有和target相同的值。
15+
16+
**算法思想**
17+
1. 使用一个计数值shift,默认值为0
18+
2. 使用for循环遍历数组,设循环变量为i
19+
- 如果遇到target,就令shift自增,继续循环;
20+
- 如果没遇到target,且shift值大于0,就将 i 当前指向的元素向前移动 shift 个位置。
21+
3. 更新数组的size, size -= shift
22+
23+
举个例子,假设数组是 [1, 3, 3, 4, 3, 5],我们要删除所有的 3。
24+
25+
在遍历过程中,每次遇到 3,shift 就增加 1。当遇到不是 3 的元素时(比如 4 和 5),我们就把这些元素向前移动 shift 个位置。
26+
27+
最后,数组变成了 [1, 4, 5, 4, 3, 5],但由于 size 减少了 shift 的值,实际有效的数组部分变成了 [1, 4, 5]
28+
29+
**算法实现(C#)**
30+
```cs
31+
public void remove(T item){
32+
int shift = 0;
33+
34+
for (int i = 0; i < size; i++){
35+
if (array[i].Equals(item)) {
36+
shift++; // 需要移除的元素计数
37+
} else if (shift > 0) {
38+
// 将当前元素向前移动 shift 个位置
39+
array[i - shift] = array[i];
40+
}
41+
}
42+
43+
size -= shift; // 更新数组大小
44+
}
45+
46+
```
47+
48+
## 我实现的Vector源码(C#)
49+
```cs
50+
using System;
51+
using System.Collections.Generic;
52+
53+
namespace HelloWorldApplication
54+
{
55+
class HelloWorld
56+
{
57+
static void Main(string[] args)
58+
{
59+
Vector<int> vector = new Vector<int>();
60+
61+
// 测试 push 和 size
62+
vector.push(1);
63+
vector.push(2);
64+
vector.push(3);
65+
Console.WriteLine("Size after 3 pushes: " + vector.Size()); // 预期输出: 3
66+
67+
// 测试 at 和 prepend
68+
vector.prepend(0);
69+
Console.WriteLine("Element at index 0: " + vector.at(0)); // 预期输出: 0
70+
71+
// 测试 insert
72+
vector.insert(2, 5);
73+
Console.WriteLine("Element at index 2: " + vector.at(2)); // 预期输出: 5
74+
75+
// 测试 pop
76+
int popped = vector.pop();
77+
Console.WriteLine("Popped element: " + popped); // 预期输出: 3
78+
Console.WriteLine("Size after pop: " + vector.Size()); // 预期输出: 4
79+
80+
// 测试 delete
81+
vector.delete(1); // 删除索引 1 的元素(原来的 5)
82+
Console.WriteLine("Element at index 1: " + vector.at(1)); // 预期输出: 5
83+
84+
// 测试 remove
85+
vector.push(2);
86+
vector.push(2);
87+
vector.remove(2); // 删除所有的 2
88+
Console.WriteLine("Size after removing 2s: " + vector.Size()); // 预期输出: 2
89+
90+
// 测试 find
91+
int index = vector.find(1);
92+
Console.WriteLine("Index of 1: " + index); // 预期输出: -1
93+
94+
Console.ReadKey();
95+
}
96+
97+
}
98+
99+
class Vector<T>{
100+
private T[] array;
101+
private int size;
102+
103+
public Vector(){
104+
array = new T[16];
105+
size = 0;
106+
}
107+
108+
public int Size(){
109+
return size;
110+
}
111+
112+
public int capacity(){
113+
return array.Length;
114+
}
115+
116+
public bool is_empty(){
117+
return size == 0;
118+
}
119+
120+
public T at(int index){
121+
if(index < 0 || index >= size){
122+
throw new IndexOutOfRangeException("下标溢出!");
123+
}
124+
return array[index];
125+
}
126+
127+
public void push(T item){
128+
if(size >= array.Length){
129+
resize(size * 2);
130+
}
131+
array[size++] = item;
132+
}
133+
134+
public void insert(int index, T item){
135+
if(index < 0 || index > size){
136+
throw new IndexOutOfRangeException("插入下标溢出!");
137+
}
138+
139+
if(size >= array.Length){
140+
resize(size * 2);
141+
}
142+
143+
for(int i = size - 1; i >= index; i--){
144+
array[i + 1] = array[i];
145+
}
146+
147+
array[index] = item;
148+
size++;
149+
}
150+
151+
public void prepend(T item){
152+
insert(0, item);
153+
}
154+
155+
public T pop(){
156+
if(size == 0){
157+
throw new IndexOutOfRangeException("数组为空!");
158+
}
159+
T res = array[--size];
160+
if(size > 0 && size == array.Length / 4){
161+
resize(array.Length / 2);
162+
}
163+
return res;
164+
}
165+
166+
public void delete(int index){
167+
if(index < 0 || index >= size){
168+
throw new IndexOutOfRangeException("删除不存在的下标!");
169+
}
170+
for(int i = index; i < size; i++){
171+
array[i] = array[i+1];
172+
}
173+
size--;
174+
}
175+
176+
public void remove(T item){
177+
int shift = 0;
178+
for(int i = 0; i < size; i++){
179+
if(array[i].Equals(item)){
180+
shift++;
181+
}
182+
else if(shift > 0){
183+
array[i - shift] = array[i];
184+
}
185+
}
186+
size -= shift;
187+
}
188+
189+
public int find(T item){
190+
for(int i = 0; i < size; i++){
191+
if(array[i].Equals(item)){
192+
return i;
193+
}
194+
}
195+
return -1;
196+
}
197+
198+
private void resize(int new_capacity){
199+
Array.Resize(ref array, new_capacity);
200+
}
201+
}
202+
203+
}
204+
205+
```

0 commit comments

Comments
 (0)