일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- Binary Tree
- 뉴욕 화장실
- Data Structure
- BST
- priority queue
- Algorithms
- hash
- HEAPS
- Linked List
- Computer Organization
- data
- algorithm
- 화장실 지도
- Data Analyst
- data scientist
- 데이터 엔지니어
- Study
- 빅데이터 지식
- Restroom
- 데이터 분석가
- Data Engineer
- Preparing for the Google Cloud Professional Data Engineer Exam
- dataStructure
- 빅데이터 커리어 가이드북
- binary search tree
- Heap
- 빅데이터
- Computer Science
- exam
- Newyork
- Today
- Total
Jaegool_'s log
IT 279: Algorithms and Data Structures, Week 2 recap 본문
Progress Check on Algorithm Analysis
1. Put these in order from lowest to highest.
Lowest
O(1)
O(log n)
O(n)
O(n log n)
O(n2)
O(n3)
Highest
2. The actual running time of a given function is determined by the expression 3n + 4 + 5n2.
What is the Big-Oh notation that accurately describes the function? c. O(n^2)
a. O(n)
b. O(3n)
3. You have analyzed a particular program to be O(n^2). Then you have run some tests with the program, producing the following table of input size and running times.
Input size | Running time in seconds |
100 | 0.010 |
400 | 0.091 |
1600 | 1.435 |
Which of the following is correct? b
a. The running times indicate that the program's computational complexity is lower than O(n^2).
b. The running times indicate that the program's computational complexity probably is O(n^2).
c. The running times indicate that the program's computational complexity is greater than O(n^2).
d. None of the above is correct.
4. What is the complexity of the following code segment:
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << "I am a loop" << endl;
}
for (int k = 0; k < n; k++)
{
cout << "I am also a loop" << endl;
}
}
n^2: The inner loops will each have a running time of n, for a total of 2n. But in Big-Oh notation, we drop the constant, so that's just n. Then we multiply that by the outer loop, which runs n times. So we end up with O(n^2)
Big-O analysis:
sum = 0;
for( i = 0; i < n; ++i )
for( j = 0; j < i * i; ++j )
for( k = 0; k < j; ++k )
++sum;
n^5: n * n^2 * n^2
sum = 0;
for( i = 1; i < n; ++i )
for( j = 1; j < i * i; ++j )
if( j % i == 0 )
for( k = 0; k < j; ++k )
++sum;
n^4: n * n^2 * n
Q. An algorithm takes 0.5 ms for input size 100. How long will it take for input size
500 if the running time is the following (assume low-order terms are negligible)?
a. linear : 2.5ms
b. O(N logN)
c. quadratic 250000/10000 * 0.5 = 25 * 0.5 = 12.5ms
d. cubic
Q. An algorithm takes 0.5 ms for input size 100. How large a problem can be solved in 1 min if the running time is the following (assume low-order terms are negligible)?
1m = 60,000 ms
a. linear
0.5 :100 = 60000 : x
X = 6000000/0.5 = 12,000,000
c. quadratic
x^2/100^2 * 0.5 = 60,000
x^2 = 60000 * 10000 / 0.5
x^2 = 1,200,000,000
x = 34641.0161514
Linked list in C++
struct
struct Node
{
int data;
Node* next;
Node(int data = 0, Node* next = nullptr){
this->data = data;
this->next = next;
}
}
Insertion Code (given temp)
Node* insertNode = new Node(6, temp->next);
temp->next = insertNode;
Searching a Linked List
public Node* searchList(Node* head, int valToFind)
{
Node* curNode = head;
while(curNode && curNode->data != valToFind)
{
curNode = curNode->next;
}
return curNode;
}
Deletion Code (given temp)
Node* deleteNode = temp -> next;
temp->next = deleteNode->next;
delete deleteNode;
Cannot write as:
temp->next = temp->next->next;
- We will get a memory leak
Double linked list (Java)
Insertion Code(after temp)
Node insertNode = new Node(8);
insertNode.next = temp.next;
insertNode.prev = temp;
temp.next = insertNode;
insertNode.next.prev = insertNode;
Progress Check on Lists
1. One approach to implementing the List ADT is to use a linked list. The other main approach (which you almost certainly learned first) is to use a(n) array.
2.
Assume you have the following C++ Node class:
class Node
{
public:
int dataVal;
Node* next;
Node(int data = 0; Node* next = nullptr) : dataVal(data), next(next) {}
};
Which of the following correctly creates a new node with the value 6 and inserts it at the front of a list? Assume the variable head points to the beginning of the list.
Node* newNode = new Node(6, head);
head = newNode;
3.
True or false: Deleting the head and the tail of a linked list will always free all of the memory in the list.
Progress Check on Data Structure Review
1. Which of the following is NOT true of abstract data types (ADTs)? b
b. ADTs are always implemented as classes.
c. We can create an ADT for an integer.
d. ADTs are not specific to any particular language.
-> b. ADTs are often implemented as classes, but they don't have to be. We can implement ADTs in languages that do not have classes.
2. Which of the problems below would be best solved using a queue? d
a. Implementing unlimited undo and redo in an application.
b. Searching for a particular item in a library of video titles.
c. Evaluating a postfix expression.
d. Implementing a waiting list system where no one is allowed special priority.
3. Which of the following is NOT an operation we would typically implement for a stack? b
a. push
b. insert
c. pop
d. isEmpty
Algorithm Analysis
Breakeven point
The "breakeven point" in time complexity refers to the input size () at which two algorithms have the same performance. It's where one algorithm starts to outperform the other. By identifying this point, one can make informed decisions on which algorithm to use based on the expected size of the input.
Linked Lists & Stacks & Queues
Abstract Data Type
- Specification of a data type, including operations.
- Describes data and operations in an implementation-independent way.
- Characteristics: Encapsulation, Data Abstraction, Modularity, Information Hiding, Standardization
Common examples of ADTs include:
- Lists
- Stacks
- Queues
- Trees
- Graphs
- ADT is not directly usable
- Most ADTs can be implemented in multiple ways
Circular lists
Circular lists, or circular linked lists, are a type of linked list where the last node in the list points back to the first node instead of having a null reference.
Benefits of Circular Lists:
- Continuous Looping: One of the primary advantages of a circular list is the ability to loop through the list continuously. For example, in multimedia applications or games where you need to rotate through elements repeatedly, a circular list provides an efficient way to cycle through the list without checking for the end and resetting.
- Simplified Insertion/Deletion at End: In a singly linked list, inserting an element at the end requires traversal of the entire list to reach the last node. But, in a circular linked list with a reference to the first node (or last node), you can easily access its predecessor and make insertions or deletions more efficiently.
- Applications in Algorithms: Circular lists can be useful in specific algorithms and problem-solving scenarios, like the Josephus problem or certain round-robin scheduling algorithms.
- Equal Distribution: In scenarios where tasks need to be distributed evenly among several entities, a circular list ensures that once the end is reached, the distribution starts again from the beginning.
- Fixed Memory Allocation: In certain embedded system applications where memory is limited, a circular buffer (a specialized kind of circular list) can be useful. It provides a fixed-size structure where new data overwrites old data when the buffer is full.
- Ease in Navigation: Moving either direction (in the case of a doubly circular linked list) becomes easier, as there's no strict "end" to the list. One can move to the previous element from the first node or to the next element from the last node directly.
Stack
LIFO(Last-In, First-Out)
Ex) backtracking, web browsers, parenthesis matching, and Syntax parsing
Queue
FIFO(First-In, First-out)
Ex) handling requests, ordering processes, web servers
The two primary options for implementing stacks or queues are:
- Array (or Dynamic Array) Implementation:
- Stack: An array can be used to implement a stack by using an index (often called the "top" index) to keep track of the top element. The push operation adds an element at the position indicated by the "top" index, and the pop operation removes it. When using a dynamic array (like an ArrayList in Java or a List in Python), the stack can grow or shrink as needed.
- Queue: An array can be used to implement a queue by using two indices: "front" and "rear". The enqueue operation adds an element at the rear, and the dequeue operation removes the element from the front. A circular array can help in efficient use of space in the array, especially when items are continuously enqueued and dequeued.
- Linked List Implementation:
- Stack: A singly linked list can implement a stack where the push operation inserts elements at the head of the list, and the pop operation removes them from the head. This approach ensures O(1) time complexity for these operations.
- Queue: A doubly-ended linked list (or a singly linked list with tail pointer) can implement a queue. The enqueue operation inserts elements at the tail, and the dequeue operation removes them from the head. Again, with this approach, both operations can be done in O(1) time if we maintain pointers to both the head and tail of the list.
'Courses' 카테고리의 다른 글
IT 279: Algorithms and Data Structures, Week 4 Search Trees (0) | 2023.10.04 |
---|---|
IT 279: Algorithms and Data Structures, Week 3 Trees recap (1) | 2023.10.04 |
IT 279: Algorithms and Data Structures, Week 1 recap (0) | 2023.10.02 |
IT 495 - Client meeting [Pixel Bit Road: funding platform for games] (0) | 2023.09.25 |
Algorithm and Data Structure Study notes, Sep [Dynamic memory arrangements] (0) | 2023.09.14 |