diff --git a/codes/kotlin/chapter_array_and_linkedlist/array.kt b/codes/kotlin/chapter_array_and_linkedlist/array.kt index b9a04a985..0fb285587 100644 --- a/codes/kotlin/chapter_array_and_linkedlist/array.kt +++ b/codes/kotlin/chapter_array_and_linkedlist/array.kt @@ -98,4 +98,4 @@ fun main() { /* 查找元素 */ val index: Int = find(nums, 3) println("在 nums 中查找元素 3 ,得到索引 = $index") -} +} \ No newline at end of file diff --git a/codes/kotlin/chapter_stack_and_queue/array_deque.kt b/codes/kotlin/chapter_stack_and_queue/array_deque.kt new file mode 100644 index 000000000..d4997e003 --- /dev/null +++ b/codes/kotlin/chapter_stack_and_queue/array_deque.kt @@ -0,0 +1,144 @@ +/** + * File: array_deque.kt + * Created Time: 2024-01-25 + * Author: curtishd (1023632660@qq.com) + */ + +package chapter_stack_and_queue + +/* 基于环形数组实现的双向队列 */ +class ArrayDeque(capacity: Int) { + private var nums = IntArray(capacity) // 用于存储双向队列元素的数组 + private var front = 0 // 队首指针,指向队首元素 + private var queSize = 0 // 双向队列长度 + + /* 获取双向队列的容量 */ + fun capacity(): Int { + return nums.size + } + + /* 获取双向队列的长度 */ + fun size(): Int { + return queSize + } + + /* 判断双向队列是否为空 */ + fun isEmpty(): Boolean { + return queSize == 0 + } + + /* 计算环形数组索引 */ + private fun index(i: Int): Int { + // 通过取余操作实现数组首尾相连 + // 当 i 越过数组尾部后,回到头部 + // 当 i 越过数组头部后,回到尾部 + return (i + capacity()) % capacity() + } + + /* 队首入队 */ + fun pushFirst(num: Int) { + if (queSize == capacity()) { + println("双向队列已满") + return + } + // 队首指针向左移动一位 + // 通过取余操作实现 front 越过数组头部后回到尾部 + front = index(front - 1) + // 将 num 添加至队首 + nums[front] = num + queSize++ + } + + /* 队尾入队 */ + fun pushLast(num: Int) { + if (queSize == capacity()) { + println("双向队列已满") + return + } + // 计算队尾指针,指向队尾索引 + 1 + val rear = index(front + queSize) + // 将 num 添加至队尾 + nums[rear] = num + queSize++ + } + + /* 队首出队 */ + fun popFirst(): Int { + val num = peekFirst() + // 队首指针向后移动一位 + front = index(front + 1) + queSize-- + return num + } + + /* 访问队尾元素 */ + fun popLast(): Int { + val num = peekLast() + queSize-- + return num + } + + /* 访问队首元素 */ + fun peekFirst(): Int { + if (isEmpty()) throw IndexOutOfBoundsException() + return nums[front] + } + + /* 访问队尾元素 */ + fun peekLast(): Int { + if (isEmpty()) throw IndexOutOfBoundsException() + // 计算尾元素索引 + val last = index(front + queSize - 1) + return nums[last] + } + + /* 返回数组用于打印 */ + fun toArray(): IntArray { + // 仅转换有效长度范围内的列表元素 + val res = IntArray(queSize) + var i = 0 + var j = front + while (i < queSize) { + res[i] = nums[index(j)] + i++ + j++ + } + return res + } +} + +/* Driver Code */ +fun main() { + /* 初始化双向队列 */ + val deque = ArrayDeque(10) + deque.pushLast(3) + deque.pushLast(2) + deque.pushLast(5) + println("双向队列 deque = ${deque.toArray().contentToString()}") + + /* 访问元素 */ + val peekFirst = deque.peekFirst() + println("队首元素 peekFirst = $peekFirst") + val peekLast = deque.peekLast() + println("队尾元素 peekLast = $peekLast") + + /* 元素入队 */ + deque.pushLast(4) + println("元素 4 队尾入队后 deque = ${deque.toArray().contentToString()}") + deque.pushFirst(1) + println("元素 1 队首入队后 deque = ${deque.toArray().contentToString()}") + + /* 元素出队 */ + val popLast = deque.popLast() + println("队尾出队元素 = ${popLast},队尾出队后 deque = ${deque.toArray().contentToString()}") + val popFirst = deque.popFirst() + println("队首出队元素 = ${popFirst},队首出队后 deque = ${deque.toArray().contentToString()}") + + /* 获取双向队列的长度 */ + val size = deque.size() + println("双向队列长度 size = $size") + + /* 判断双向队列是否为空 */ + val isEmpty = deque.isEmpty() + println("双向队列是否为空 = $isEmpty") +} \ No newline at end of file diff --git a/codes/kotlin/chapter_stack_and_queue/array_queue.kt b/codes/kotlin/chapter_stack_and_queue/array_queue.kt new file mode 100644 index 000000000..eaf6a7cce --- /dev/null +++ b/codes/kotlin/chapter_stack_and_queue/array_queue.kt @@ -0,0 +1,110 @@ +/** + * File: array_queue.kt + * Created Time: 2024-01-25 + * Author: curtishd (1023632660@qq.com) + */ + +package chapter_stack_and_queue + +/* 基于环形数组实现的队列 */ +class ArrayQueue(capacity: Int) { + private val nums = IntArray(capacity) // 用于存储队列元素的数组 + private var front = 0 // 队首指针,指向队首元素 + private var queSize = 0 // 队列长度 + + /* 获取队列的容量 */ + fun capacity(): Int { + return nums.size + } + + /* 获取队列的长度 */ + fun size(): Int { + return queSize + } + + /* 判断队列是否为空 */ + fun isEmpty(): Boolean { + return queSize == 0 + } + + /* 入队 */ + fun push(num: Int) { + if (queSize == capacity()) { + println("队列已满") + return + } + // 计算队尾指针,指向队尾索引 + 1 + // 通过取余操作实现 rear 越过数组尾部后回到头部 + val rear = (front + queSize) % capacity() + // 将 num 添加至队尾 + nums[rear] = num + queSize++ + } + + /* 出队 */ + fun pop(): Int { + val num = peek() + // 队首指针向后移动一位,若越过尾部,则返回到数组头部 + front = (front + 1) % capacity() + queSize-- + return num + } + + /* 访问队首元素 */ + fun peek(): Int { + if (isEmpty()) throw IndexOutOfBoundsException() + return nums[front] + } + + /* 返回数组 */ + fun toArray(): IntArray { + // 仅转换有效长度范围内的列表元素 + val res = IntArray(queSize) + var i = 0 + var j = front + while (i < queSize) { + res[i] = nums[j % capacity()] + i++ + j++ + } + return res + } +} + +/* Driver Code */ +fun main() { + /* 初始化队列 */ + val capacity = 10 + val queue = ArrayQueue(capacity) + + /* 元素入队 */ + queue.push(1) + queue.push(3) + queue.push(2) + queue.push(5) + queue.push(4) + println("队列 queue = ${queue.toArray().contentToString()}") + + /* 访问队首元素 */ + val peek = queue.peek() + println("队首元素 peek = $peek") + + /* 元素出队 */ + val pop = queue.pop() + println("出队元素 pop = ${pop},出队后 queue = ${queue.toArray().contentToString()}") + + /* 获取队列的长度 */ + val size = queue.size() + println("队列长度 size = $size") + + /* 判断队列是否为空 */ + val isEmpty = queue.isEmpty() + println("队列是否为空 = $isEmpty") + + /* 测试环形数组 */ + for (i in 0..9) { + queue.push(i) + queue.pop() + println("第 $i 轮入队 + 出队后 queue = ${queue.toArray().contentToString()}") + } +} \ No newline at end of file diff --git a/codes/kotlin/chapter_stack_and_queue/array_stack.kt b/codes/kotlin/chapter_stack_and_queue/array_stack.kt new file mode 100644 index 000000000..efef9aab5 --- /dev/null +++ b/codes/kotlin/chapter_stack_and_queue/array_stack.kt @@ -0,0 +1,75 @@ +/** + * File: array_stack.kt + * Created Time: 2024-01-25 + * Author: curtishd (1023632660@qq.com) + */ + +package chapter_stack_and_queue + +/* 基于数组实现的栈 */ +class ArrayStack { + // 初始化列表(动态数组) + private val stack = ArrayList() + + /* 获取栈的长度 */ + fun size(): Int { + return stack.size + } + + /* 判断栈是否为空 */ + fun isEmpty(): Boolean { + return size() == 0 + } + + /* 入栈 */ + fun push(num: Int) { + stack.add(num) + } + + /* 出栈 */ + fun pop(): Int { + if (isEmpty()) throw IndexOutOfBoundsException() + return stack.removeAt(size() - 1) + } + + /* 访问栈顶元素 */ + fun peek(): Int { + if (isEmpty()) throw IndexOutOfBoundsException() + return stack[size() - 1] + } + + /* 将 List 转化为 Array 并返回 */ + fun toArray(): Array { + return stack.toArray() + } +} + +/* Driver Code */ +fun main() { + /* 初始化栈 */ + val stack = ArrayStack() + + /* 元素入栈 */ + stack.push(1) + stack.push(3) + stack.push(2) + stack.push(5) + stack.push(4) + println("栈 stack = ${stack.toArray().contentToString()}") + + /* 访问栈顶元素 */ + val peek = stack.peek() + println("栈顶元素 peek = $peek") + + /* 元素出栈 */ + val pop = stack.pop() + println("出栈元素 pop = ${pop},出栈后 stack = ${stack.toArray().contentToString()}") + + /* 获取栈的长度 */ + val size = stack.size() + println("栈的长度 size = $size") + + /* 判断是否为空 */ + val isEmpty = stack.isEmpty() + println("栈是否为空 = $isEmpty") +} \ No newline at end of file diff --git a/codes/kotlin/chapter_stack_and_queue/deque.kt b/codes/kotlin/chapter_stack_and_queue/deque.kt new file mode 100644 index 000000000..703133529 --- /dev/null +++ b/codes/kotlin/chapter_stack_and_queue/deque.kt @@ -0,0 +1,45 @@ +/** + * File: deque.kt + * Created Time: 2024-01-25 + * Author: curtishd (1023632660@qq.com) + */ + +package chapter_stack_and_queue + +import java.util.* + +/* Driver Code */ +fun main() { + /* 初始化双向队列 */ + val deque = LinkedList() + deque.offerLast(3) + deque.offerLast(2) + deque.offerLast(5) + println("双向队列 deque = $deque") + + /* 访问元素 */ + val peekFirst = deque.peekFirst() + println("队首元素 peekFirst = $peekFirst") + val peekLast = deque.peekLast() + println("队尾元素 peekLast = $peekLast") + + /* 元素入队 */ + deque.offerLast(4) + println("元素 4 队尾入队后 deque = $deque") + deque.offerFirst(1) + println("元素 1 队首入队后 deque = $deque") + + /* 元素出队 */ + val popLast = deque.pollLast() + println("队尾出队元素 = $popLast,队尾出队后 deque = $deque") + val popFirst = deque.pollFirst() + println("队首出队元素 = $popFirst,队首出队后 deque = $deque") + + /* 获取双向队列的长度 */ + val size = deque.size + println("双向队列长度 size = $size") + + /* 判断双向队列是否为空 */ + val isEmpty = deque.isEmpty() + println("双向队列是否为空 = $isEmpty") +} \ No newline at end of file diff --git a/codes/kotlin/chapter_stack_and_queue/linkedlist_deque.kt b/codes/kotlin/chapter_stack_and_queue/linkedlist_deque.kt new file mode 100644 index 000000000..cc2a5c232 --- /dev/null +++ b/codes/kotlin/chapter_stack_and_queue/linkedlist_deque.kt @@ -0,0 +1,166 @@ +/** + * File: linkedlist_deque.kt + * Created Time: 2024-01-25 + * Author: curtishd (1023632660@qq.com) + */ + +package chapter_stack_and_queue + +/* 双向链表节点 */ +class ListNode(var value: Int) { + // 节点值 + var next: ListNode? = null // 后继节点引用 + var prev: ListNode? = null // 前驱节点引用 +} + +/* 基于双向链表实现的双向队列 */ +class LinkedListDeque { + private var front: ListNode? = null // 头节点 front ,尾节点 rear + private var rear: ListNode? = null + private var queSize = 0 // 双向队列的长度 + + /* 获取双向队列的长度 */ + fun size(): Int { + return queSize + } + + /* 判断双向队列是否为空 */ + fun isEmpty(): Boolean { + return size() == 0 + } + + /* 入队操作 */ + fun push(num: Int, isFront: Boolean) { + val node = ListNode(num) + // 若链表为空,则令 front 和 rear 都指向 node + if (isEmpty()) { + rear = node + front = rear + // 队首入队操作 + } else if (isFront) { + // 将 node 添加至链表头部 + front?.prev = node + node.next = front + front = node // 更新头节点 + // 队尾入队操作 + } else { + // 将 node 添加至链表尾部 + rear?.next = node + node.prev = rear + rear = node // 更新尾节点 + } + queSize++ // 更新队列长度 + } + + /* 队首入队 */ + fun pushFirst(num: Int) { + push(num, true) + } + + /* 队尾入队 */ + fun pushLast(num: Int) { + push(num, false) + } + + /* 出队操作 */ + fun pop(isFront: Boolean): Int { + if (isEmpty()) throw IndexOutOfBoundsException() + + val value: Int + // 队首出队操作 + if (isFront) { + value = front!!.value // 暂存头节点值 + // 删除头节点 + val fNext = front!!.next + if (fNext != null) { + fNext.prev = null + front!!.next = null + } + front = fNext // 更新头节点 + // 队尾出队操作 + } else { + value = rear!!.value // 暂存尾节点值 + // 删除尾节点 + val rPrev = rear!!.prev + if (rPrev != null) { + rPrev.next = null + rear!!.prev = null + } + rear = rPrev // 更新尾节点 + } + queSize-- // 更新队列长度 + return value + } + + /* 队首出队 */ + fun popFirst(): Int { + return pop(true) + } + + /* 队尾出队 */ + fun popLast(): Int { + return pop(false) + } + + /* 访问队首元素 */ + fun peekFirst(): Int { + if (isEmpty()) { + throw IndexOutOfBoundsException() + + } + return front!!.value + } + + /* 访问队尾元素 */ + fun peekLast(): Int { + if (isEmpty()) throw IndexOutOfBoundsException() + return rear!!.value + } + + /* 返回数组用于打印 */ + fun toArray(): IntArray { + var node = front + val res = IntArray(size()) + for (i in res.indices) { + res[i] = node!!.value + node = node.next + } + return res + } +} + +/* Driver Code */ +fun main() { + /* 初始化双向队列 */ + val deque = LinkedListDeque() + deque.pushLast(3) + deque.pushLast(2) + deque.pushLast(5) + println("双向队列 deque = ${deque.toArray().contentToString()}") + + /* 访问元素 */ + val peekFirst = deque.peekFirst() + println("队首元素 peekFirst = $peekFirst") + val peekLast = deque.peekLast() + println("队尾元素 peekLast = $peekLast") + + /* 元素入队 */ + deque.pushLast(4) + println("元素 4 队尾入队后 deque = ${deque.toArray().contentToString()}") + deque.pushFirst(1) + println("元素 1 队首入队后 deque = ${deque.toArray().contentToString()}") + + /* 元素出队 */ + val popLast = deque.popLast() + println("队尾出队元素 = ${popLast},队尾出队后 deque = ${deque.toArray().contentToString()}") + val popFirst = deque.popFirst() + println("队首出队元素 = ${popFirst},队首出队后 deque = ${deque.toArray().contentToString()}") + + /* 获取双向队列的长度 */ + val size = deque.size() + println("双向队列长度 size = $size") + + /* 判断双向队列是否为空 */ + val isEmpty = deque.isEmpty() + println("双向队列是否为空 = $isEmpty") +} \ No newline at end of file diff --git a/codes/kotlin/chapter_stack_and_queue/linkedlist_queue.kt b/codes/kotlin/chapter_stack_and_queue/linkedlist_queue.kt new file mode 100644 index 000000000..5267b493a --- /dev/null +++ b/codes/kotlin/chapter_stack_and_queue/linkedlist_queue.kt @@ -0,0 +1,97 @@ +/** + * File: linkedlist_queue.kt + * Created Time: 2024-01-25 + * Author: curtishd (1023632660@qq.com) + */ + +package chapter_stack_and_queue + +class LinkedListQueue( + // 头节点 front ,尾节点 rear + private var front: ListNode? = null, + private var rear: ListNode? = null, + private var queSize: Int = 0 +) { + + /* 获取队列的长度 */ + fun size(): Int { + return queSize + } + + /* 判断队列是否为空 */ + fun isEmpty(): Boolean { + return size() == 0 + } + + /* 入队 */ + fun push(num: Int) { + // 在尾节点后添加 num + val node = ListNode(num) + // 如果队列为空,则令头、尾节点都指向该节点 + if (front == null) { + front = node + rear = node + // 如果队列不为空,则将该节点添加到尾节点后 + } else { + rear?.next = node + rear = node + } + queSize++ + } + + /* 出队 */ + fun pop(): Int { + val num = peek() + // 删除头节点 + front = front?.next + queSize-- + return num + } + + /* 访问队首元素 */ + fun peek(): Int { + if (isEmpty()) throw IndexOutOfBoundsException() + return front!!.value + } + + /* 将链表转化为 Array 并返回 */ + fun toArray(): IntArray { + var node = front + val res = IntArray(size()) + for (i in res.indices) { + res[i] = node!!.value + node = node.next + } + return res + } +} + +/* Driver Code */ +fun main() { + /* 初始化队列 */ + val queue = LinkedListQueue() + + /* 元素入队 */ + queue.push(1) + queue.push(3) + queue.push(2) + queue.push(5) + queue.push(4) + println("队列 queue = ${queue.toArray().contentToString()}") + + /* 访问队首元素 */ + val peek = queue.peek() + println("队首元素 peek = $peek") + + /* 元素出队 */ + val pop = queue.pop() + println("出队元素 pop = $pop,出队后 queue = ${queue.toArray().contentToString()}") + + /* 获取队列的长度 */ + val size = queue.size() + println("队列长度 size = $size") + + /* 判断队列是否为空 */ + val isEmpty = queue.isEmpty() + println("队列是否为空 = $isEmpty") +} \ No newline at end of file diff --git a/codes/kotlin/chapter_stack_and_queue/linkedlist_stack.kt b/codes/kotlin/chapter_stack_and_queue/linkedlist_stack.kt new file mode 100644 index 000000000..eb138f4d5 --- /dev/null +++ b/codes/kotlin/chapter_stack_and_queue/linkedlist_stack.kt @@ -0,0 +1,86 @@ +/** + * File: linkedlist_stack.kt + * Created Time: 2024-01-25 + * Author: curtishd (1023632660@qq.com) + */ + +package chapter_stack_and_queue + +class LinkedListStack( + private var stackPeek: ListNode? = null, // 将头节点作为栈顶 + private var stkSize: Int = 0 // 栈的长度 +) { + + /* 获取栈的长度 */ + fun size(): Int { + return stkSize + } + + /* 判断栈是否为空 */ + fun isEmpty(): Boolean { + return size() == 0 + } + + /* 入栈 */ + fun push(num: Int) { + val node = ListNode(num) + node.next = stackPeek + stackPeek = node + stkSize++ + } + + /* 出栈 */ + fun pop(): Int? { + val num = peek() + stackPeek = stackPeek?.next + stkSize--; + return num + } + + /* 访问栈顶元素 */ + fun peek(): Int? { + if (isEmpty()) throw IndexOutOfBoundsException() + return stackPeek?.value + } + + /* 将 List 转化为 Array 并返回 */ + fun toArray(): IntArray { + var node = stackPeek + val res = IntArray(size()) + for (i in res.size - 1 downTo 0) { + res[i] = node?.value!! + node = node.next + } + return res + } +} + +/* Driver Code */ +fun main() { + /* 初始化栈 */ + val stack = LinkedListStack() + + /* 元素入栈 */ + stack.push(1) + stack.push(3) + stack.push(2) + stack.push(5) + stack.push(4) + println("栈 stack = ${stack.toArray().contentToString()}") + + /* 访问栈顶元素 */ + val peek = stack.peek()!! + println("栈顶元素 peek = $peek") + + /* 元素出栈 */ + val pop = stack.pop()!! + println("出栈元素 pop = $pop,出栈后 stack = ${stack.toArray().contentToString()}") + + /* 获取栈的长度 */ + val size = stack.size() + println("栈的长度 size = $size") + + /* 判断是否为空 */ + val isEmpty = stack.isEmpty() + println("栈是否为空 = $isEmpty") +} \ No newline at end of file diff --git a/codes/kotlin/chapter_stack_and_queue/queue.kt b/codes/kotlin/chapter_stack_and_queue/queue.kt new file mode 100644 index 000000000..5f87fcc1e --- /dev/null +++ b/codes/kotlin/chapter_stack_and_queue/queue.kt @@ -0,0 +1,39 @@ +/** + * File: queue.kt + * Created Time: 2024-01-25 + * Author: curtishd (1023632660@qq.com) + */ + +package chapter_stack_and_queue + +import java.util.* + +/* Driver Code */ +fun main() { + /* 初始化队列 */ + val queue = LinkedList() + + /* 元素入队 */ + queue.offer(1) + queue.offer(3) + queue.offer(2) + queue.offer(5) + queue.offer(4) + println("队列 queue = $queue") + + /* 访问队首元素 */ + val peek = queue.peek() + println("队首元素 peek = $peek") + + /* 元素出队 */ + val pop = queue.poll() + println("出队元素 pop = $pop,出队后 queue = $queue") + + /* 获取队列的长度 */ + val size = queue.size + println("队列长度 size = $size") + + /* 判断队列是否为空 */ + val isEmpty = queue.isEmpty() + println("队列是否为空 = $isEmpty") +} \ No newline at end of file diff --git a/codes/kotlin/chapter_stack_and_queue/stack.kt b/codes/kotlin/chapter_stack_and_queue/stack.kt new file mode 100644 index 000000000..51a3be98f --- /dev/null +++ b/codes/kotlin/chapter_stack_and_queue/stack.kt @@ -0,0 +1,39 @@ +/** + * File: stack.kt + * Created Time: 2024-01-25 + * Author: curtishd (1023632660@qq.com) + */ + +package chapter_stack_and_queue + +import java.util.* + +/* Driver Code */ +fun main() { + /* 初始化栈 */ + val stack = Stack() + + /* 元素入栈 */ + stack.push(1) + stack.push(3) + stack.push(2) + stack.push(5) + stack.push(4) + println("栈 stack = $stack") + + /* 访问栈顶元素 */ + val peek = stack.peek() + println("栈顶元素 peek = $peek") + + /* 元素出栈 */ + val pop = stack.pop() + println("出栈元素 pop = $pop,出栈后 stack = $stack") + + /* 获取栈的长度 */ + val size = stack.size + println("栈的长度 size = $size") + + /* 判断是否为空 */ + val isEmpty = stack.isEmpty() + println("栈是否为空 = $isEmpty") +} \ No newline at end of file