mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 06:07:20 +08:00 
			
		
		
		
	add dart chapter_array_and_linkedlist (#338)
* add dart chapter_array_and_linkedlist * update my_list.dart * update chapter_array_and_linkedlist * Update my_list.dart * Update array.dart --------- Co-authored-by: huangjianqing <huangjianqing@52tt.com> Co-authored-by: Yudong Jin <krahets@163.com>
This commit is contained in:
		
							
								
								
									
										107
									
								
								codes/dart/chapter_array_and_linkedlist/array.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								codes/dart/chapter_array_and_linkedlist/array.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,107 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: array.dart
 | 
			
		||||
 * Created Time: 2023-01-20
 | 
			
		||||
 * Author: Jefferson (JeffersonHuang77@gmail.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import 'dart:math';
 | 
			
		||||
 | 
			
		||||
class Array {
 | 
			
		||||
  /* 随机返回一个 数组元素 */
 | 
			
		||||
  int randomAccess(List nums) {
 | 
			
		||||
    // 在区间[0,size) 中随机抽取一个数字
 | 
			
		||||
    int randomIndex = Random().nextInt(nums.length);
 | 
			
		||||
    // 获取并返回随机元素
 | 
			
		||||
    int randomNum = nums[randomIndex];
 | 
			
		||||
    return randomNum;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 扩展数组长度 */
 | 
			
		||||
  List extend(List nums, int enlarge) {
 | 
			
		||||
    // 初始化一个扩展长度后的数组,元素初始值为0
 | 
			
		||||
    List<int> res = List.filled(nums.length + enlarge, 0);
 | 
			
		||||
 | 
			
		||||
    // 将原数组中的所有元素复制到新数组
 | 
			
		||||
    for (var i = 0; i < nums.length; i++) {
 | 
			
		||||
      res[i] = nums[i];
 | 
			
		||||
    }
 | 
			
		||||
    // 返回扩展后的新数组
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 在数组的索引 index 处插入元素 num */
 | 
			
		||||
  void insert(List nums, int num, int index) {
 | 
			
		||||
    // 把索引index以及之后的所有元素向后移动一位
 | 
			
		||||
    for (var i = nums.length - 1; i > index; i--) {
 | 
			
		||||
      nums[i] = nums[i - 1];
 | 
			
		||||
    }
 | 
			
		||||
    // 将 num 赋给 index 处元素
 | 
			
		||||
    nums[index] = num;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 删除索引 index 处元素 */
 | 
			
		||||
  void remove(List nums, int index) {
 | 
			
		||||
    for (var i = index; i < nums.length - 1; i++) {
 | 
			
		||||
      nums[i] = nums[i + 1];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 遍历数组元素 */
 | 
			
		||||
  void traverse(List nums) {
 | 
			
		||||
    var count = 0;
 | 
			
		||||
    // 通过索引遍历数组
 | 
			
		||||
    for (var i = 0; i < nums.length; i++) {
 | 
			
		||||
      count++;
 | 
			
		||||
    }
 | 
			
		||||
    // 直接遍历数组
 | 
			
		||||
    for (var num in nums) {
 | 
			
		||||
      count++;
 | 
			
		||||
    }
 | 
			
		||||
    // 通过forEach方法遍历数组
 | 
			
		||||
    nums.forEach((element) {
 | 
			
		||||
      count++;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 在数组中查找指定元素 */
 | 
			
		||||
  int find(List nums, int target) {
 | 
			
		||||
    for (var i = 0; i < nums.length; i++) {
 | 
			
		||||
      if (nums[i] == target) return i;
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Driver Code */
 | 
			
		||||
int main() {
 | 
			
		||||
  /* 初始化固定长度数组 */
 | 
			
		||||
  var arr = List.filled(5, 0);
 | 
			
		||||
  print('数组 arr = $arr');
 | 
			
		||||
  List nums = [1, 3, 2, 5, 4];
 | 
			
		||||
  print('数组 nums = $nums');
 | 
			
		||||
 | 
			
		||||
  /* 随机访问 */
 | 
			
		||||
  int randomNum = Array().randomAccess(nums);
 | 
			
		||||
  print('在 nums 中获取随机元素 $randomNum');
 | 
			
		||||
 | 
			
		||||
  /* 长度扩展 */
 | 
			
		||||
  nums = Array().extend(nums, 3);
 | 
			
		||||
  print('将数组长度扩展至 8, 得到nums = $nums');
 | 
			
		||||
 | 
			
		||||
  /* 插入元素 */
 | 
			
		||||
  Array().insert(nums, 6, 3);
 | 
			
		||||
  print("在索引 3 处插入数字 6 ,得到 nums = $nums");
 | 
			
		||||
 | 
			
		||||
  /* 删除元素 */
 | 
			
		||||
  Array().remove(nums, 2);
 | 
			
		||||
  print("删除索引 2 处的元素,得到 nums = $nums");
 | 
			
		||||
 | 
			
		||||
  /* 遍历元素 */
 | 
			
		||||
  Array().traverse(nums);
 | 
			
		||||
 | 
			
		||||
  /* 查找元素 */
 | 
			
		||||
  int index = Array().find(nums, 3);
 | 
			
		||||
  print("在 nums 中查找元素 3 ,得到索引 = $index");
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								codes/dart/chapter_array_and_linkedlist/linked_list.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								codes/dart/chapter_array_and_linkedlist/linked_list.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: linked_list.dart
 | 
			
		||||
 * Created Time: 2023-01-23
 | 
			
		||||
 * Author: Jefferson (JeffersonHuang77@gmail.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import '../utils/ListNode.dart';
 | 
			
		||||
import '../utils/PrintUtil.dart';
 | 
			
		||||
 | 
			
		||||
class LinkedList {
 | 
			
		||||
  /* 在链表的结点 n0 之后插入结点 P */
 | 
			
		||||
  void insert(ListNode n0, ListNode P) {
 | 
			
		||||
    ListNode? n1 = n0.next;
 | 
			
		||||
    n0.next = P;
 | 
			
		||||
    P.next = n1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 删除链表的结点 n0 之后的首个结点 */
 | 
			
		||||
  void remove(ListNode n0) {
 | 
			
		||||
    if (n0.next == null) return;
 | 
			
		||||
    ListNode P = n0.next!;
 | 
			
		||||
    ListNode? n1 = P.next;
 | 
			
		||||
    n0.next = n1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 访问链表中索引为 index 的结点 */
 | 
			
		||||
  ListNode? access(ListNode? head, int index) {
 | 
			
		||||
    for (var i = 0; i < index; i++) {
 | 
			
		||||
      if (head == null) return null;
 | 
			
		||||
      head = head.next;
 | 
			
		||||
    }
 | 
			
		||||
    return head;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 在链表中查找值为 target 的首个结点 */
 | 
			
		||||
  int find(ListNode? head, int target) {
 | 
			
		||||
    int index = 0;
 | 
			
		||||
    while (head != null) {
 | 
			
		||||
      if (head.val == target) {
 | 
			
		||||
        return index;
 | 
			
		||||
      }
 | 
			
		||||
      head = head.next;
 | 
			
		||||
      index++;
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Driver Code */
 | 
			
		||||
int main() {
 | 
			
		||||
  // 初始化链表
 | 
			
		||||
  //初始化各个结点
 | 
			
		||||
  ListNode n0 = ListNode(1);
 | 
			
		||||
  ListNode n1 = ListNode(3);
 | 
			
		||||
  ListNode n2 = ListNode(2);
 | 
			
		||||
  ListNode n3 = ListNode(5);
 | 
			
		||||
  ListNode n4 = ListNode(4);
 | 
			
		||||
  // 构建引用指向
 | 
			
		||||
  n0.next = n1;
 | 
			
		||||
  n1.next = n2;
 | 
			
		||||
  n2.next = n3;
 | 
			
		||||
  n3.next = n4;
 | 
			
		||||
 | 
			
		||||
  print('初始化的链表为');
 | 
			
		||||
  PrintUtil().printLinkedList(n0);
 | 
			
		||||
 | 
			
		||||
  /* 插入结点 */
 | 
			
		||||
  LinkedList().insert(n0, ListNode(0));
 | 
			
		||||
  PrintUtil().printLinkedList(n0);
 | 
			
		||||
 | 
			
		||||
  /* 删除结点 */
 | 
			
		||||
  LinkedList().remove(n0);
 | 
			
		||||
  PrintUtil().printLinkedList(n0);
 | 
			
		||||
 | 
			
		||||
  /* 访问结点 */
 | 
			
		||||
  ListNode? node = LinkedList().access(n0, 3);
 | 
			
		||||
  print('链表中索引 3 处的结点的值 = ${node!.val}');
 | 
			
		||||
 | 
			
		||||
  /* 查找结点 */
 | 
			
		||||
  int index = LinkedList().find(n0, 2);
 | 
			
		||||
  print('链表中值为 2 的结点的索引 = $index');
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								codes/dart/chapter_array_and_linkedlist/list.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								codes/dart/chapter_array_and_linkedlist/list.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: list.dart
 | 
			
		||||
 * Created Time: 2023-01-24
 | 
			
		||||
 * Author: Jefferson (JeffersonHuang77@gmail.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
  /* 初始化列表 */
 | 
			
		||||
  List<int> list = [1,3,2,5,4];
 | 
			
		||||
  print('列表 list = $list');
 | 
			
		||||
 | 
			
		||||
  /* 访问元素 */
 | 
			
		||||
  int num = list[1];
 | 
			
		||||
  print('访问索引 1 处的元素,得到 num =  $num');
 | 
			
		||||
 | 
			
		||||
  /* 更新元素 */
 | 
			
		||||
  list[1] = 0;
 | 
			
		||||
  print('将索引 1 处的元素更新为 0 ,得到 list = $list');
 | 
			
		||||
 | 
			
		||||
  /* 清空列表 */
 | 
			
		||||
  list.clear();
 | 
			
		||||
  print('清空列表后 list = $list');
 | 
			
		||||
 | 
			
		||||
  /* 尾部添加元素 */
 | 
			
		||||
  list.add(1);
 | 
			
		||||
  list.add(3);
 | 
			
		||||
  list.add(2);
 | 
			
		||||
  list.add(5);
 | 
			
		||||
  list.add(4);
 | 
			
		||||
  print('添加元素后 list = $list');
 | 
			
		||||
 | 
			
		||||
  /* 中间插入元素 */
 | 
			
		||||
  list.insert(3, 6);
 | 
			
		||||
  print('在索引 3 处插入数字 6 ,得到 list = $list');
 | 
			
		||||
 | 
			
		||||
  /* 删除元素 */
 | 
			
		||||
  list.remove(3);
 | 
			
		||||
 | 
			
		||||
  /* 通过索引遍历列表 */
 | 
			
		||||
  int count = 0;
 | 
			
		||||
  for (var i = 0; i < list.length; i++) {
 | 
			
		||||
    count++;
 | 
			
		||||
  }
 | 
			
		||||
  /* 直接遍历列表元素 */
 | 
			
		||||
  count = 0;
 | 
			
		||||
  for (var n in list) {
 | 
			
		||||
    count++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 拼接两个列表 */
 | 
			
		||||
  List<int> list1 = [6,8,7,10,9];
 | 
			
		||||
  list.addAll(list1);
 | 
			
		||||
  print('将列表 list1 拼接到 list 之后,得到 list = $list');
 | 
			
		||||
 | 
			
		||||
  /* 排序列表 */
 | 
			
		||||
  list.sort();
 | 
			
		||||
  print('排序列表后 list = $list');
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										132
									
								
								codes/dart/chapter_array_and_linkedlist/my_list.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								codes/dart/chapter_array_and_linkedlist/my_list.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,132 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: my_list.dart
 | 
			
		||||
 * Created Time: 2023-02-05
 | 
			
		||||
 * Author: Jefferson (JeffersonHuang77@gmail.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* 列表类简易实现 */
 | 
			
		||||
class MyList {
 | 
			
		||||
  late List<int> _nums; // 数组(存储列表元素)
 | 
			
		||||
  int _capacity = 10; // 列表容量
 | 
			
		||||
  int _size = 0; // 列表长度(即当前元素数量)
 | 
			
		||||
  int _extendRatio = 2; // 每次列表扩容的倍数
 | 
			
		||||
 | 
			
		||||
  /* 构造函数 */
 | 
			
		||||
  MyList() {
 | 
			
		||||
    _nums = List.filled(_capacity, 0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 获取列表长度(即当前元素数量)*/
 | 
			
		||||
  int size() => _size;
 | 
			
		||||
 | 
			
		||||
  /* 获取列表容量 */
 | 
			
		||||
  int capacity() => _capacity;
 | 
			
		||||
 | 
			
		||||
  /* 访问元素 */
 | 
			
		||||
  int get(int index) {
 | 
			
		||||
    if (index >= _size) throw RangeError('索引越界');
 | 
			
		||||
    return _nums[index];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 更新元素 */
 | 
			
		||||
  void set(int index, int num) {
 | 
			
		||||
    if (index >= _size) throw RangeError('索引越界');
 | 
			
		||||
    _nums[index] = num;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 尾部添加元素 */
 | 
			
		||||
  void add(int num) {
 | 
			
		||||
    // 元素数量超出容量时,触发扩容机制
 | 
			
		||||
    if (_size == _capacity) extendCapacity();
 | 
			
		||||
    _nums[_size] = num;
 | 
			
		||||
    // 更新元素数量
 | 
			
		||||
    _size++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 中间插入元素 */
 | 
			
		||||
  void insert(int index, int num) {
 | 
			
		||||
    if (index >= _size) throw RangeError('索引越界');
 | 
			
		||||
    // 元素数量超出容量时,触发扩容机制
 | 
			
		||||
    if (_size == _capacity) extendCapacity();
 | 
			
		||||
    // 将索引 index 以及之后的元素都向后移动一位
 | 
			
		||||
    for (var j = _size - 1; j >= index; j--) {
 | 
			
		||||
      _nums[j + 1] = _nums[j];
 | 
			
		||||
    }
 | 
			
		||||
    _nums[index] = num;
 | 
			
		||||
    // 更新元素数量
 | 
			
		||||
    _size++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 删除元素 */
 | 
			
		||||
  int remove(int index) {
 | 
			
		||||
    if (index >= _size) throw RangeError('索引越界');
 | 
			
		||||
    int num = _nums[index];
 | 
			
		||||
    // 将索引 index 之后的元素都向前移动一位
 | 
			
		||||
    for (var j = index; j < _size - 1; j++) {
 | 
			
		||||
      _nums[j] = _nums[j + 1];
 | 
			
		||||
    }
 | 
			
		||||
    // 更新元素数量
 | 
			
		||||
    _size--;
 | 
			
		||||
    // 返回被删除元素
 | 
			
		||||
    return num;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 列表扩容 */
 | 
			
		||||
  void extendCapacity() {
 | 
			
		||||
    // 新建一个长度为 _capacity * _extendRatio 的数组
 | 
			
		||||
    final _newNums = List.filled(_capacity * _extendRatio, 0);
 | 
			
		||||
    // 将原数组拷贝到新数组
 | 
			
		||||
    List.copyRange(_newNums, 0, _nums);
 | 
			
		||||
    // 更新 _nums 的引用
 | 
			
		||||
    _nums = _newNums;
 | 
			
		||||
    // 更新列表容量
 | 
			
		||||
    _capacity = _nums.length;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 将列表转换为数组 */
 | 
			
		||||
  List<int> toArray() {
 | 
			
		||||
    List<int> nums = [];
 | 
			
		||||
    for (var i = 0; i < _size; i++) {
 | 
			
		||||
      nums.add(get(i));
 | 
			
		||||
    }
 | 
			
		||||
    return nums;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Driver Code */
 | 
			
		||||
int main() {
 | 
			
		||||
  /* 初始化列表 */
 | 
			
		||||
  MyList list = MyList();
 | 
			
		||||
  /* 尾部添加元素 */
 | 
			
		||||
  list.add(1);
 | 
			
		||||
  list.add(3);
 | 
			
		||||
  list.add(2);
 | 
			
		||||
  list.add(5);
 | 
			
		||||
  list.add(4);
 | 
			
		||||
  print('列表 list = ${list.toArray()},容量 =  ${list.capacity()},长度 = ${list.size()}');
 | 
			
		||||
 | 
			
		||||
  /* 中间插入元素 */
 | 
			
		||||
  list.insert(3, 6);
 | 
			
		||||
  print('在索引 3 处插入数字 6 ,得到 list =  ${list.toArray()}');
 | 
			
		||||
 | 
			
		||||
  /* 删除元素 */
 | 
			
		||||
  list.remove(3);
 | 
			
		||||
  print('删除索引 3 处的元素,得到 list = ${list.toArray()}');
 | 
			
		||||
 | 
			
		||||
  /* 访问元素 */
 | 
			
		||||
  int num = list.get(1);
 | 
			
		||||
  print('访问索引 1 处的元素,得到 num =  $num');
 | 
			
		||||
 | 
			
		||||
  /* 更新元素 */
 | 
			
		||||
  list.set(1, 0);
 | 
			
		||||
  print('将索引 1 处的元素更新为 0 ,得到 list =  ${list.toArray()}');
 | 
			
		||||
 | 
			
		||||
  /* 测试扩容机制 */
 | 
			
		||||
  for (var i = 0; i < 10; i++) {
 | 
			
		||||
    // 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制
 | 
			
		||||
    list.add(i);
 | 
			
		||||
  }
 | 
			
		||||
  print('扩容后的列表 list = ${list.toArray()},容量 = ${list.capacity()}  ,长度 = ${list.size()}');
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								codes/dart/utils/ListNode.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								codes/dart/utils/ListNode.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: ListNode
 | 
			
		||||
 * Created Time: 2023-01-23
 | 
			
		||||
 * Author: Jefferson (JeffersonHuang77@gmail.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Definition for a singly-linked list node
 | 
			
		||||
 */
 | 
			
		||||
class ListNode {
 | 
			
		||||
  int val;
 | 
			
		||||
  ListNode? next;
 | 
			
		||||
 | 
			
		||||
  ListNode(this.val, [this.next]);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  String toString() {
 | 
			
		||||
    return 'ListNode{val: $val, next: $next}';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								codes/dart/utils/PrintUtil.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								codes/dart/utils/PrintUtil.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: PrintUtil
 | 
			
		||||
 * Created Time: 2023-01-23
 | 
			
		||||
 * Author: Jefferson (JeffersonHuang77@gmail.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import 'ListNode.dart';
 | 
			
		||||
 | 
			
		||||
class PrintUtil {
 | 
			
		||||
    
 | 
			
		||||
  void printLinkedList(ListNode? head) {
 | 
			
		||||
    List<String> list = [];
 | 
			
		||||
 | 
			
		||||
    while (head != null) {
 | 
			
		||||
      list.add('${head.val}');
 | 
			
		||||
      head = head.next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    print(list.join(' -> '));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user