Renamed top-level folders to use underscores instead of dashes.

This commit is contained in:
Donne Martin
2015-06-28 06:39:24 -04:00
parent d44ed31ef9
commit 7573730e39
53 changed files with 0 additions and 0 deletions

View File

187
stacks_queues/hanoi.ipynb Normal file
View File

@@ -0,0 +1,187 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<small><i>This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://bit.ly/code-notes).</i></small>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Implement the [Towers of Hanoi](http://en.wikipedia.org/wiki/Tower_of_Hanoi) with 3 towers and N disks.\n",
"\n",
"* [Constraints and Assumptions](#Constraints-and-Assumptions)\n",
"* [Test Cases](#Test-Cases)\n",
"* [Algorithm](#Algorithm)\n",
"* [Code](#Code)\n",
"* [Unit Test](#Unit-Test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Constraints and Assumptions\n",
"\n",
"*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n",
"\n",
"* Can we assume we already have a stack class that can be used for this problem?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"* NULL towers\n",
"* 0 disks\n",
"* 1 disk\n",
"* 2 or more disks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"* Create three stacks to represent each tower\n",
"* def hanoi(n, src, dest, buffer):\n",
" * If 0 disks return\n",
" * hanoi(n-1, src, buffer)\n",
" * Move remaining element from src to dest\n",
" * hanoi(n-1, buffer, dest) \n",
"\n",
"Complexity:\n",
"* Time: O(2^n)\n",
"* Space: O(m) where m is the number of recursion levels"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%run stack.py"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def hanoi(num_disks, src, dest, buff):\n",
" if src is None or dest is None or buff is None:\n",
" return\n",
" if num_disks > 0:\n",
" hanoi(num_disks-1, src, buff, dest)\n",
" data = src.pop()\n",
" dest.push(data)\n",
" hanoi(num_disks-1, buff, dest, src)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test\n",
"\n",
"*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test: NULL towers\n",
"Test: 0 disks\n",
"Test: 1 disk\n",
"Test: 2 or more disks\n",
"Success: test_hanoi\n"
]
}
],
"source": [
"from nose.tools import assert_equal\n",
"\n",
"class Test(object):\n",
" def test_hanoi(self):\n",
" num_disks = 3\n",
" src = Stack()\n",
" buff = Stack()\n",
" dest = Stack()\n",
"\n",
" print('Test: NULL towers')\n",
" hanoi(num_disks, None, None, None)\n",
"\n",
" print('Test: 0 disks')\n",
" hanoi(num_disks, src, dest, buff)\n",
" assert_equal(dest.pop(), None)\n",
"\n",
" print('Test: 1 disk')\n",
" src.push(5)\n",
" hanoi(num_disks, src, dest, buff)\n",
" assert_equal(dest.pop(), 5)\n",
"\n",
" print('Test: 2 or more disks')\n",
" for i in xrange(num_disks, -1, -1):\n",
" src.push(i)\n",
" hanoi(num_disks, src, dest, buff)\n",
" for i in xrange(0, num_disks):\n",
" assert_equal(dest.pop(), i)\n",
"\n",
" print('Success: test_hanoi')\n",
"\n",
"if __name__ == '__main__':\n",
" test = Test()\n",
" test.test_hanoi()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

View File

@@ -0,0 +1,227 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<small><i>This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://bit.ly/code-notes).</i></small>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Implement n stacks using a single array.\n",
"\n",
"* [Constraints and Assumptions](#Constraints-and-Assumptions)\n",
"* [Test Cases](#Test-Cases)\n",
"* [Algorithm](#Algorithm)\n",
"* [Code](#Code)\n",
"* [Unit Test](#Unit-Test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Constraints and Assumptions\n",
"\n",
"*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n",
"\n",
"* Are the stacks and array a fixed size?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"* Test the following on the three stacks:\n",
" * Push to full stack\n",
" * Push to non-full stack\n",
" * Pop on empty stack\n",
" * Pop on non-empty stack"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"### Absolute Index\n",
"\n",
"* return stack size * stack index + stack pointer\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)\n",
"\n",
"### Push\n",
"\n",
"* If stack is full, throw exception\n",
"* Else\n",
" * Increment stack pointer\n",
" * Get the absolute array index\n",
" * Insert the value to this index\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)\n",
"\n",
"### Pop\n",
"\n",
"* If stack is empty, throw exception\n",
"* Else\n",
" * Store the value contained in the absolute array index\n",
" * Set the value in the absolute array index to None\n",
" * Decrement stack pointer\n",
" * return value\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"class Stacks(object):\n",
" def __init__(self, num_stacks, stack_size):\n",
" self.num_stacks = num_stacks\n",
" self.stack_size = stack_size\n",
" self.stack_pointers = [-1] * num_stacks\n",
" self.stack_array = [None] * num_stacks * stack_size\n",
"\n",
" def abs_index(self, stack_index):\n",
" return stack_index * self.stack_size + self.stack_pointers[stack_index]\n",
"\n",
" def push(self, stack_index, data):\n",
" if self.stack_pointers[stack_index] == self.stack_size - 1:\n",
" raise Exception('Stack is full')\n",
" else:\n",
" self.stack_pointers[stack_index] += 1\n",
" array_index = self.abs_index(stack_index)\n",
" self.stack_array[array_index] = data\n",
"\n",
" def pop(self, stack_index):\n",
" if self.stack_pointers[stack_index] == -1:\n",
" raise Exception('Stack is empty')\n",
" else:\n",
" array_index = self.abs_index(stack_index) \n",
" data = self.stack_array[array_index]\n",
" self.stack_array[array_index] = None\n",
" self.stack_pointers[stack_index] -= 1\n",
" return data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test\n",
"\n",
"*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test: Pop on empty stack\n",
"Test: Push to full stack\n",
"Test: Push to non-full stack\n",
"Test: Pop on non-empty stack\n",
"Success: test_stacks\n",
"\n"
]
}
],
"source": [
"from nose.tools import assert_equal\n",
"from nose.tools import raises\n",
"\n",
"class Test(object):\n",
" @raises(Exception)\n",
" def test_pop_on_empty(self, num_stacks, stack_size):\n",
" print('Test: Pop on empty stack')\n",
" stacks = Stacks(num_stacks, stack_size)\n",
" stacks.pop(0)\n",
"\n",
" @raises(Exception)\n",
" def test_push_on_full(self, num_stacks, stack_size):\n",
" print('Test: Push to full stack')\n",
" stacks = Stacks(num_stacks, stack_size)\n",
" for i in xrange(0, stack_size):\n",
" stacks.push(2, i)\n",
" stacks.push(2, stack_size)\n",
"\n",
" def test_stacks(self, num_stacks, stack_size):\n",
" print('Test: Push to non-full stack')\n",
" stacks = Stacks(num_stacks, stack_size)\n",
" stacks.push(0, 1)\n",
" stacks.push(0, 2)\n",
" stacks.push(1, 3)\n",
" stacks.push(2, 4)\n",
"\n",
" print('Test: Pop on non-empty stack')\n",
" assert_equal(stacks.pop(0), 2)\n",
" assert_equal(stacks.pop(0), 1)\n",
" assert_equal(stacks.pop(1), 3)\n",
" assert_equal(stacks.pop(2), 4)\n",
"\n",
" print('Success: test_stacks\\n')\n",
"\n",
"if __name__ == '__main__':\n",
" num_stacks = 3\n",
" stack_size = 100 \n",
" test = Test()\n",
" test.test_pop_on_empty(num_stacks, stack_size)\n",
" test.test_push_on_full(num_stacks, stack_size)\n",
" test.test_stacks(num_stacks, stack_size)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

View File

@@ -0,0 +1,226 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<small><i>This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://bit.ly/code-notes).</i></small>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Implement a queue using two stacks.\n",
"\n",
"* [Constraints and Assumptions](#Constraints-and-Assumptions)\n",
"* [Test Cases](#Test-Cases)\n",
"* [Algorithm](#Algorithm)\n",
"* [Code](#Code)\n",
"* [Unit Test](#Unit-Test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Constraints and Assumptions\n",
"\n",
"*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n",
"\n",
"* Do you expect the methods to be enqueue and dequeue?\n",
" * Yes\n",
"* Can we assume we already have a stack class that can be used for this problem?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"* Enqueue and dequeue on empty stack\n",
"* Enqueue and dequeue on non-empty stack\n",
"* Multiple enqueue in a row\n",
"* Multiple dequeue in a row\n",
"* Enqueue after a dequeue\n",
"* Dequeue after an enqueue"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"We'll use two stacks (left and right) to implement the queue. The left stack will be used for enqueue and the right stack will be used for dequeue.\n",
"\n",
"To prevent multiple dequeue calls from needlessly shifting elements around between the stacks, we'll shift elements in a lazy manner.\n",
"\n",
"### Enqueue\n",
"\n",
"* If the left stack is empty and the right stack is not empty\n",
" * Shift the elements of the right stack to the left stack\n",
"* Push the data to the left stack\n",
"\n",
"Complexity:\n",
"* Time: O(n)\n",
"* Space: O(n)\n",
"\n",
"### Dequeue\n",
"\n",
"* If the right stack is empty and the the left stack is not empty\n",
" * Shift the elements of the left stack to the right stack\n",
"* Pop from the right stack and return the data\n",
"\n",
"Complexity:\n",
"* Time: O(n)\n",
"* Space: O(n)\n",
"\n",
"### Shift Stacks\n",
"\n",
"* While the source stack has elements:\n",
" * Pop from the source stack and push the data to the destination stack\n",
"\n",
"Complexity:\n",
"* Time: O(n)\n",
"* Space: O(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%run stack.py"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class QueueFromStacks(object):\n",
" def __init__(self):\n",
" self.left_stack = Stack()\n",
" self.right_stack = Stack()\n",
"\n",
" def shift_stacks(self, source, destination):\n",
" while source.peek() is not None:\n",
" destination.push(source.pop())\n",
"\n",
" def enqueue(self, data):\n",
" if self.left_stack.is_empty() and not self.right_stack.is_empty():\n",
" self.shift_stacks(self.right_stack, self.left_stack)\n",
" self.left_stack.push(data)\n",
"\n",
" def dequeue(self):\n",
" if self.right_stack.is_empty() and not self.left_stack.is_empty():\n",
" self.shift_stacks(self.left_stack, self.right_stack)\n",
" return self.right_stack.pop()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test\n",
"\n",
"*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test: Dequeue on empty stack\n",
"Test: Enqueue on empty stack\n",
"Test: Enqueue on non-empty stack\n",
"Test: Multiple enqueue in a row\n",
"Test: Dequeue on non-empty stack\n",
"Test: Dequeue after an enqueue\n",
"Test: Multiple dequeue in a row\n",
"Test: Enqueue after a dequeue\n",
"Success: test_queue_from_stacks\n"
]
}
],
"source": [
"from nose.tools import assert_equal\n",
"\n",
"class Test(object):\n",
" def test_queue_from_stacks(self):\n",
" print('Test: Dequeue on empty stack')\n",
" queue = QueueFromStacks()\n",
" assert_equal(queue.dequeue(), None)\n",
"\n",
" print('Test: Enqueue on empty stack')\n",
" print('Test: Enqueue on non-empty stack')\n",
" print('Test: Multiple enqueue in a row')\n",
" num_items = 3\n",
" for i in range (0, num_items):\n",
" queue.enqueue(i)\n",
"\n",
" print('Test: Dequeue on non-empty stack')\n",
" print('Test: Dequeue after an enqueue')\n",
" assert_equal(queue.dequeue(), 0)\n",
"\n",
" print('Test: Multiple dequeue in a row')\n",
" assert_equal(queue.dequeue(), 1)\n",
" assert_equal(queue.dequeue(), 2)\n",
"\n",
" print('Test: Enqueue after a dequeue')\n",
" queue.enqueue(5)\n",
" assert_equal(queue.dequeue(), 5)\n",
"\n",
" print('Success: test_queue_from_stacks')\n",
"\n",
"if __name__ == '__main__':\n",
" test = Test()\n",
" test.test_queue_from_stacks()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

View File

@@ -0,0 +1,278 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<small><i>This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://bit.ly/code-notes).</i></small>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Implement a queue with enqueue and dequeue methods using a linked list.\n",
"\n",
"* [Constraints and Assumptions](#Constraints-and-Assumptions)\n",
"* [Test Cases](#Test-Cases)\n",
"* [Algorithm](#Algorithm)\n",
"* [Code](#Code)\n",
"* [Unit Test](#Unit-Test)\n",
"* [Pythonic-Code](#Pythonic-Code)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Constraints and Assumptions\n",
"\n",
"*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n",
"\n",
"* If there is one item in the list, do you expect the first and last pointers to both point to it?\n",
" * Yes\n",
"* If there are no items on the list, do you expect the first and last pointers to be NULL?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"### Enqueue\n",
"\n",
"* Enqueue to an empty queue\n",
"* Enqueue to a non-empty queue\n",
"\n",
"### Dequeue\n",
"\n",
"* Dequeue an empty queue\n",
"* Dequeue a queue with one element\n",
"* Dequeue a queue with more than one element"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"### Enqueue\n",
"\n",
"* If the list is empty, set first and last to node\n",
"* Else, set last to node\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)\n",
"\n",
"### Dequeue\n",
"\n",
"* If the list is empty, return NULL\n",
"* If the list has one node\n",
" * Save the first node's value\n",
" * Set first and last to NULL\n",
" * Return the saved value\n",
"* Else\n",
" * Save the first node's value\n",
" * Set first to its next node\n",
" * Return the saved value\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Overwriting queue_list.py\n"
]
}
],
"source": [
"%%writefile queue_list.py\n",
"# Need to avoid naming this queue.py as it \n",
"# will conflict with IPython Notebook\n",
"\n",
"class Node(object):\n",
" def __init__(self, data):\n",
" self.data = data\n",
" self.next = None\n",
"\n",
"class Queue(object):\n",
" def __init__(self):\n",
" self.first = None\n",
" self.last = None\n",
"\n",
" def enqueue(self, data):\n",
" node = Node(data)\n",
" if self.first is None and self.last is None:\n",
" self.first = node\n",
" self.last = node\n",
" else:\n",
" self.last.next = node\n",
" self.last = node\n",
"\n",
" def dequeue(self):\n",
" # Empty list\n",
" if self.first is None and self.last is None:\n",
" return None\n",
" \n",
" # Remove only element from a one element list\n",
" elif self.first == self.last:\n",
" data = self.first.data\n",
" self.first = None\n",
" self.last = None\n",
" return data\n",
" else:\n",
" data = self.first.data\n",
" self.first = self.first.next\n",
" return data"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%run queue_list.py"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test\n",
"\n",
"*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test: Dequeue an empty queue\n",
"Test: Enqueue to an empty queue\n",
"Test: Dequeue a queue with one element\n",
"Test: Enqueue to a non-empty queue\n",
"Test: Dequeue a queue with more than one element\n",
"Success: test_end_to_end\n"
]
}
],
"source": [
"from nose.tools import assert_equal\n",
"\n",
"class Test(object):\n",
" # TODO: It would be better if we had unit tests for each\n",
" # method in addition to the following end-to-end test\n",
" def test_end_to_end(self):\n",
" print('Test: Dequeue an empty queue')\n",
" queue = Queue()\n",
" assert_equal(queue.dequeue(), None)\n",
"\n",
" print('Test: Enqueue to an empty queue')\n",
" queue.enqueue(1)\n",
"\n",
" print('Test: Dequeue a queue with one element')\n",
" assert_equal(queue.dequeue(), 1)\n",
"\n",
" print('Test: Enqueue to a non-empty queue')\n",
" queue.enqueue(2)\n",
" queue.enqueue(3)\n",
" queue.enqueue(4)\n",
"\n",
" print('Test: Dequeue a queue with more than one element')\n",
" assert_equal(queue.dequeue(), 2)\n",
" assert_equal(queue.dequeue(), 3)\n",
" assert_equal(queue.dequeue(), 4)\n",
" \n",
" print('Success: test_end_to_end')\n",
"\n",
"if __name__ == '__main__':\n",
" test = Test()\n",
" test.test_end_to_end()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Pythonic-Code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Source: https://docs.python.org/2/tutorial/datastructures.html#using-lists-as-queues\n",
"<pre>\n",
"It is possible to use a list as a queue, where the first element added is the first element retrieved (“first-in, first-out”); however, lists are not efficient for this purpose. While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).\n",
"\n",
"To implement a queue, use collections.deque which was designed to have fast appends and pops from both ends. For example:\n",
"\n",
">>>\n",
">>> from collections import deque\n",
">>> queue = deque([\"Eric\", \"John\", \"Michael\"])\n",
">>> queue.append(\"Terry\") # Terry arrives\n",
">>> queue.append(\"Graham\") # Graham arrives\n",
">>> queue.popleft() # The first to arrive now leaves\n",
"'Eric'\n",
">>> queue.popleft() # The second to arrive now leaves\n",
"'John'\n",
">>> queue # Remaining queue in order of arrival\n",
"deque(['Michael', 'Terry', 'Graham'])\n",
"</pre>"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

View File

@@ -0,0 +1,36 @@
# Need to avoid naming this queue.py as it
# will conflict with IPython Notebook
class Node(object):
def __init__(self, data):
self.data = data
self.next = None
class Queue(object):
def __init__(self):
self.first = None
self.last = None
def enqueue(self, data):
node = Node(data)
if self.first is None and self.last is None:
self.first = node
self.last = node
else:
self.last.next = node
self.last = node
def dequeue(self):
# Empty list
if self.first is None and self.last is None:
return None
# Remove only element from a one element list
elif self.first == self.last:
data = self.first.data
self.first = None
self.last = None
return data
else:
data = self.first.data
self.first = self.first.next
return data

View File

@@ -0,0 +1,242 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<small><i>This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://bit.ly/code-notes).</i></small>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Implement SetOfStacks that wraps a list of stacks, where each stack is bound by a capacity.\n",
"\n",
"* [Constraints and Assumptions](#Constraints-and-Assumptions)\n",
"* [Test Cases](#Test-Cases)\n",
"* [Algorithm](#Algorithm)\n",
"* [Code](#Code)\n",
"* [Unit Test](#Unit-Test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Constraints and Assumptions\n",
"\n",
"*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n",
"\n",
"* Can we assume we already have a stack class that can be used for this problem?\n",
" * Yes\n",
"* If a stack becomes full, we should automatically create one?\n",
" * Yes\n",
"* If a stack becomes empty, should we delete it?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"* Push and pop on an empty stack\n",
"* Push and pop on a non-empty stack\n",
"* Push on a capacity stack to create a new one\n",
"* Pop on a one element stack to destroy it"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"### Push\n",
"\n",
"* If there are no stacks or the last stack is full\n",
" * Create a new stack\n",
"* Push to the new stack\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)\n",
"\n",
"### Pop\n",
"\n",
"* If there are no stacks, return None\n",
"* Else if the last stack has one element\n",
" * Pop the last element's data\n",
" * Delete the now empty stack\n",
" * Update the last stack pointer\n",
"* Else Pop the last element's data\n",
"* Return the last element's data\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%run stack.py"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class StackWithCapacity(Stack):\n",
" def __init__(self, top=None, capacity=10):\n",
" self.capacity = capacity\n",
" self.num_items = 0\n",
" super(StackWithCapacity, self).__init__(top)\n",
"\n",
" def push(self, data):\n",
" if self.num_items < self.capacity:\n",
" super(StackWithCapacity, self).push(data)\n",
" self.num_items += 1\n",
" else:\n",
" raise Exception('Stack full')\n",
"\n",
" def pop(self):\n",
" data = super(StackWithCapacity, self).pop()\n",
" self.num_items -= 1\n",
" return data\n",
"\n",
" def is_full(self):\n",
" return self.num_items == self.capacity\n",
"\n",
"class SetOfStacks(object):\n",
" def __init__(self, capacity):\n",
" self.capacity = capacity\n",
" self.stacks = []\n",
" self.last_stack = None\n",
"\n",
" def push(self, data):\n",
" if self.last_stack is None or self.last_stack.is_full():\n",
" self.last_stack = StackWithCapacity(None, self.capacity)\n",
" self.stacks.append(self.last_stack)\n",
" self.last_stack.push(data)\n",
"\n",
" def pop(self):\n",
" if self.last_stack is None:\n",
" return\n",
" elif self.last_stack.top.next is None:\n",
" data = self.last_stack.pop()\n",
" self.stacks.pop()\n",
" num_stacks = len(self.stacks)\n",
" if num_stacks == 0:\n",
" self.last_stack = None\n",
" else:\n",
" self.last_stack = self.stacks[num_stacks-1]\n",
" else:\n",
" data = self.last_stack.pop()\n",
" return data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test\n",
"\n",
"*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test: Push on an empty stack\n",
"Test: Push on a non-empty stack\n",
"Test: Push on a capacity stack to create a new one\n",
"Test: Pop on a one element stack to destroy it\n",
"Test: Pop general case\n",
"Test: Pop on no elements\n",
"Success: test_set_of_stacks\n"
]
}
],
"source": [
"from nose.tools import assert_equal\n",
"\n",
"class Test(object):\n",
" def test_set_of_stacks(self):\n",
" print('Test: Push on an empty stack')\n",
" capacity = 2\n",
" stacks = SetOfStacks(capacity)\n",
" stacks.push(3)\n",
"\n",
" print('Test: Push on a non-empty stack')\n",
" stacks.push(5)\n",
"\n",
" print('Test: Push on a capacity stack to create a new one')\n",
" stacks.push('a')\n",
"\n",
" print('Test: Pop on a one element stack to destroy it')\n",
" assert_equal(stacks.pop(), 'a')\n",
"\n",
" print('Test: Pop general case')\n",
" assert_equal(stacks.pop(), 5)\n",
" assert_equal(stacks.pop(), 3)\n",
"\n",
" print('Test: Pop on no elements')\n",
" assert_equal(stacks.pop(), None)\n",
" \n",
" print('Success: test_set_of_stacks')\n",
"\n",
"if __name__ == '__main__':\n",
" test = Test()\n",
" test.test_set_of_stacks()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

View File

@@ -0,0 +1,193 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<small><i>This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://bit.ly/code-notes).</i></small>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Sort a stack. You can use another stack as a buffer.\n",
"\n",
"* [Constraints and Assumptions](#Constraints-and-Assumptions)\n",
"* [Test Cases](#Test-Cases)\n",
"* [Algorithm](#Algorithm)\n",
"* [Code](#Code)\n",
"* [Unit Test](#Unit-Test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Constraints and Assumptions\n",
"\n",
"*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n",
"\n",
"* When sorted, should the largest element be at the top or bottom?\n",
" * Top\n",
"* Can you have duplicate values like 5, 5?\n",
" * Yes\n",
"* Can we assume we already have a stack class that can be used for this problem?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"* Empty stack\n",
"* One element stack\n",
"* Two or more element stack (general case)\n",
"* Already sorted stack"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"* Our buffer will hold elements in reverse sorted order, smallest at the top\n",
"* Store the current top element in a temp variable\n",
"* While stack is not empty\n",
" * While buffer is empty or buffer top is > than temp\n",
" * Move buffer top to stack\n",
" * Move temp to top of buffer\n",
"* Return buffer\n",
"\n",
"Complexity:\n",
"* Time: O(n^2)\n",
"* Space: O(n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%run stack.py"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class MyStack(Stack):\n",
" def sort(self):\n",
" buff = MyStack()\n",
" while not self.is_empty():\n",
" temp = self.pop()\n",
" while not buff.is_empty() and buff.peek() > temp:\n",
" self.push(buff.pop())\n",
" buff.push(temp)\n",
" return buff"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test\n",
"\n",
"*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test: Empty stack\n",
"Test: One element stack\n",
"Test: Two or more element stack (general case)\n",
"Success: test_sort_stack\n"
]
}
],
"source": [
"from random import randint\n",
"from nose.tools import assert_equal\n",
"\n",
"class Test(object):\n",
" def get_sorted_stack(self, numbers):\n",
" stack = MyStack()\n",
" for x in numbers:\n",
" stack.push(x)\n",
" sorted_stack = stack.sort()\n",
" return sorted_stack\n",
"\n",
" def test_sort_stack(self):\n",
" print('Test: Empty stack')\n",
" sorted_stack = self.get_sorted_stack([])\n",
" assert_equal(sorted_stack.pop(), None)\n",
"\n",
" print('Test: One element stack')\n",
" sorted_stack = self.get_sorted_stack([1])\n",
" assert_equal(sorted_stack.pop(), 1)\n",
"\n",
" print('Test: Two or more element stack (general case)')\n",
" num_items = 10\n",
" numbers = [randint(0, 10) for x in xrange(num_items)]\n",
" sorted_stack = self.get_sorted_stack(numbers)\n",
" sorted_numbers = []\n",
" for _ in xrange(num_items):\n",
" sorted_numbers.append(sorted_stack.pop())\n",
" assert_equal(sorted_numbers, sorted(numbers, reverse=True))\n",
" \n",
" print('Success: test_sort_stack')\n",
"\n",
"if __name__ == '__main__':\n",
" test = Test()\n",
" test.test_sort_stack()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

View File

@@ -0,0 +1,226 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<small><i>This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://bit.ly/code-notes).</i></small>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Implement a stack with push, pop, and min methods running O(1) time.\n",
"\n",
"* [Constraints and Assumptions](#Constraints-and-Assumptions)\n",
"* [Test Cases](#Test-Cases)\n",
"* [Algorithm](#Algorithm)\n",
"* [Code](#Code)\n",
"* [Unit Test](#Unit-Test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Constraints and Assumptions\n",
"\n",
"*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n",
"\n",
"* Can we assume this is a stack of ints?\n",
" * Yes\n",
"* Can we assume we already have a stack class that can be used for this problem?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"* Push/pop on empty stack\n",
"* Push/pop on non-empty stack"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"We'll use a second stack to keep track of the minimum values.\n",
"\n",
"### Min\n",
"\n",
"* If the second stack is empty, return an error code (max int value)\n",
"* Else, return the top of the stack, without popping it\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)\n",
"\n",
"### Push\n",
"\n",
"* Push the data\n",
"* If the data is less than min\n",
" * Push data to second stack\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(n)\n",
"\n",
"### Pop\n",
"\n",
"* Pop the data\n",
"* If the data is equal to min\n",
" * Pop the top of the second stack\n",
"* Return the data\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%run stack.py"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import sys\n",
"\n",
"class MyStack(Stack):\n",
" def __init__(self, top=None):\n",
" self.min_vals = Stack()\n",
" super(MyStack, self).__init__(top)\n",
"\n",
" def min(self):\n",
" if self.min_vals.top is None:\n",
" return sys.maxint\n",
" else:\n",
" return self.min_vals.peek()\n",
"\n",
" def push(self, data):\n",
" super(MyStack, self).push(data)\n",
" if data < self.min():\n",
" self.min_vals.push(data)\n",
"\n",
" def pop(self):\n",
" data = super(MyStack, self).pop()\n",
" if data == self.min():\n",
" self.min_vals.pop()\n",
" return data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test\n",
"\n",
"*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test: Push on empty stack, non-empty stack\n",
"Test: Pop on non-empty stack\n",
"Test: Pop empty stack\n",
"Success: test_stack_min\n"
]
}
],
"source": [
"from nose.tools import assert_equal\n",
"\n",
"class Test(object):\n",
" def test_stack_min(self):\n",
" print('Test: Push on empty stack, non-empty stack')\n",
" stack = MyStack()\n",
" stack.push(5)\n",
" assert_equal(stack.peek(), 5)\n",
" assert_equal(stack.min(), 5)\n",
" stack.push(1)\n",
" assert_equal(stack.peek(), 1)\n",
" assert_equal(stack.min(), 1)\n",
" stack.push(3)\n",
" assert_equal(stack.peek(), 3)\n",
" assert_equal(stack.min(), 1)\n",
" stack.push(0)\n",
" assert_equal(stack.peek(), 0)\n",
" assert_equal(stack.min(), 0)\n",
"\n",
" print('Test: Pop on non-empty stack')\n",
" assert_equal(stack.pop(), 0)\n",
" assert_equal(stack.min(), 1)\n",
" assert_equal(stack.pop(), 3)\n",
" assert_equal(stack.min(), 1)\n",
" assert_equal(stack.pop(), 1)\n",
" assert_equal(stack.min(), 5)\n",
" assert_equal(stack.pop(), 5)\n",
" assert_equal(stack.min(), sys.maxint)\n",
"\n",
" print('Test: Pop empty stack')\n",
" assert_equal(stack.pop(), None)\n",
" \n",
" print('Success: test_stack_min')\n",
"\n",
"if __name__ == '__main__':\n",
" test = Test()\n",
" test.test_stack_min()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

297
stacks_queues/stack.ipynb Normal file
View File

@@ -0,0 +1,297 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<small><i>This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://bit.ly/code-notes).</i></small>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Implement a stack with push, pop, peek, and is_empty methods using a linked list.\n",
"\n",
"* [Constraints and Assumptions](#Constraints-and-Assumptions)\n",
"* [Test Cases](#Test-Cases)\n",
"* [Algorithm](#Algorithm)\n",
"* [Code](#Code)\n",
"* [Unit Test](#Unit-Test)\n",
"* [Pythonic-Code](#Pythonic-Code)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Constraints and Assumptions\n",
"\n",
"*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n",
"\n",
"* None"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"### Push\n",
"\n",
"* Push to empty stack\n",
"* Push to non-empty stack\n",
"\n",
"### Pop\n",
"\n",
"* Pop on empty stack\n",
"* Pop on single element stack\n",
"* Pop on multiple element stack\n",
"\n",
"### Peek\n",
"\n",
"* Peek on empty stack\n",
"* Peek on one or more element stack\n",
"\n",
"### Is Empty\n",
"\n",
"* Is empty on empty stack\n",
"* Is empty on one or more element stack"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"### Push\n",
"\n",
"* Create new node with value\n",
"* Set node's next to top\n",
"* Set top to node\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)\n",
"\n",
"### Pop\n",
"\n",
"* If stack is empty, return NULL\n",
"* Else \n",
" * Save top's value\n",
" * Set top to top.next\n",
" * Return saved value\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)\n",
"\n",
"### Peek\n",
"\n",
"* If stack is empty, return NULL\n",
"* Else return top's value\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)\n",
"\n",
"### Is Empty\n",
"* If peek has a value, return False\n",
"* Else return True\n",
"\n",
"Complexity:\n",
"* Time: O(1)\n",
"* Space: O(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Overwriting stack.py\n"
]
}
],
"source": [
"%%writefile stack.py\n",
"\n",
"class Node(object):\n",
" def __init__(self, data):\n",
" self.data = data\n",
" self.next = None\n",
"\n",
"class Stack(object):\n",
" def __init__(self, top=None):\n",
" self.top = top\n",
"\n",
" def push(self, data):\n",
" node = Node(data)\n",
" node.next = self.top\n",
" self.top = node\n",
"\n",
" def pop(self):\n",
" if self.top is not None:\n",
" data = self.top.data\n",
" self.top = self.top.next\n",
" return data\n",
" return None\n",
"\n",
" def peek(self):\n",
" if self.top is not None:\n",
" return self.top.data\n",
" return None\n",
"\n",
" def is_empty(self):\n",
" return self.peek() is None"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%run stack.py"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test\n",
"\n",
"*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test: Empty stack\n",
"Test: One element\n",
"Test: More than one element\n",
"Success: test_end_to_end\n"
]
}
],
"source": [
"from nose.tools import assert_equal\n",
"\n",
"class Test(object):\n",
" # TODO: It would be better if we had unit tests for each\n",
" # method in addition to the following end-to-end test\n",
" def test_end_to_end(self):\n",
" print('Test: Empty stack')\n",
" stack = Stack()\n",
" assert_equal(stack.peek(), None)\n",
" assert_equal(stack.pop(), None)\n",
"\n",
" print('Test: One element')\n",
" top = Node(5)\n",
" stack = Stack(top)\n",
" assert_equal(stack.pop(), 5)\n",
" assert_equal(stack.peek(), None)\n",
"\n",
" print('Test: More than one element')\n",
" stack = Stack()\n",
" stack.push(1)\n",
" stack.push(2)\n",
" stack.push(3)\n",
" assert_equal(stack.pop(), 3)\n",
" assert_equal(stack.peek(), 2)\n",
" assert_equal(stack.pop(), 2)\n",
" assert_equal(stack.peek(), 1)\n",
" assert_equal(stack.is_empty(), False)\n",
" assert_equal(stack.pop(), 1)\n",
" assert_equal(stack.peek(), None)\n",
" assert_equal(stack.is_empty(), True)\n",
" \n",
" print('Success: test_end_to_end')\n",
"\n",
"if __name__ == '__main__':\n",
" test = Test()\n",
" test.test_end_to_end()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Pythonic-Code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Source: https://docs.python.org/2/tutorial/datastructures.html#using-lists-as-stacks\n",
"<pre>\n",
"5.1.1. Using Lists as Stacks\n",
"The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved (“last-in, first-out”). To add an item to the top of the stack, use append(). To retrieve an item from the top of the stack, use pop() without an explicit index. For example:\n",
"\n",
">>> stack = [3, 4, 5]\n",
">>> stack.append(6)\n",
">>> stack.append(7)\n",
">>> stack\n",
"[3, 4, 5, 6, 7]\n",
">>> stack.pop()\n",
"7\n",
">>> stack\n",
"[3, 4, 5, 6]\n",
">>> stack.pop()\n",
"6\n",
">>> stack.pop()\n",
"5\n",
">>> stack\n",
"[3, 4]\n",
"</pre>"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

29
stacks_queues/stack.py Normal file
View File

@@ -0,0 +1,29 @@
class Node(object):
def __init__(self, data):
self.data = data
self.next = None
class Stack(object):
def __init__(self, top=None):
self.top = top
def push(self, data):
node = Node(data)
node.next = self.top
self.top = node
def pop(self):
if self.top is not None:
data = self.top.data
self.top = self.top.next
return data
return None
def peek(self):
if self.top is not None:
return self.top.data
return None
def is_empty(self):
return self.peek() is None

View File