
English: 
OK.
Today we are going to talk
about a very interesting
algorithm called Quicksort --
-- which was invented by Tony
Hoare in 1962.
And it has ended up being a
really interesting algorithm
from many points of view.
And because of that,
it turns out today's lecture is
going to be both hard and fast.
If you see the person next to
you sleeping,
you will want to say let's get
going.

Korean: 
이 강의 한글자막은 www.snow.or.kr 자원활동가들에 의해 작성되었습니다. 
좋아요. 오늘 우리는 퀵 정렬이라는 
매우 흥미로운 알고리즘에 대해 이야기해 볼 것입니다. 
그것은 1962년에 Tony Hoare에 의해 고안된 것입니다. 
그리고 그것은 매우 많은 관점으로부터 정말 흥미로운 알고리즘이 되었습니다. 
그리고 그것 때문에, 
오늘 강의는 어렵고 빠르게 진행 될 것입니다. 
만약 여러분이 여러분의 옆 친구가 졸고 있는 것을 보면, 
여러분은 가자 라고 말하길 원할 것입니다. 

Korean: 
퀵 정렬은 분할 정복 알고리즘입니다.
그리고 정렬합니다, 
그것은 그것들이 있는 곳에서 인자들을 재배열합니다. 
그것은 삽입정렬이 그것들이 있는 곳에서 
인자를 재배열하는 것과 같습니다. 
합병 정렬은 그렇지 않습니다. 합병 정렬은 합병 연산을 하기 위해 
여분의 저장을 필요로 합니다. 
선형 시간과 장소에서 합병을 하기 위해, 그것은 선형시간에서 장소에서 합병하지 않습니다. 
그것은 단지 재배열함으로써 하지 않습니다. 
그것은 좋습니다 왜냐하면 그것은 그것의 
저장 사용에 있어서 꽤 효율적이기 때문입니다. 
또한 매우 실용적입니다 
여러분이 약간 조율한다면요. 기본 알고리즘은, 
여러분이 그것을 구현하면, 그것은 필수적으로 그리 효율적이지는 않습니다.

English: 
It's a divide-and-conquer
algorithm.
And it sorts,
as they say,
in place, meaning that it just
rearranged the elements where
they are.
That is like insertion sort
rearranges elements where they
are.
Mergesort does not.
Mergesort requires extra
storage in order to do the merge
operation.
To merge in linear time and
place, it doesn't merge in place
in linear time.
It doesn't do it just by
rearranging.
It is nice because it is in
place, so that means that it is
fairly efficient in its use of
storage.
And it also happens to be very
practical if you tune it a bit.
The basic algorithm turns out,
if you just implement that,
it's not necessarily that

Korean: 
그러나 여러분이 하는 것이 
표준이면 여러분은 어떤 것의 런타임을 신장시킵니다, 
그리고 우리는 그것들이 무엇인지에 대해 약간 이야기할 것입니다, 
그리고 나서 그것은 매우, 매우 실용적입니다. 
그래서, 그것은 분할 정복 패러다임을 사용합니다. 
첫 번째 단계는 분할입니다. 그리고 이것을 하기 위해  
기본적으로 그것은 분할함으로써 동작합니다.
그래서 그것은 입력 배열을 두 하위 배열로 나눕니다 우리는 중심(pivot)이라고 부르는 인자 주변에서요.

English: 
efficient.
But if what you do was then do
the standard kinds of things you
do to goose up the runtime of
something, and we'll talk a
little about what those things
are, then it can be very,
very practical.
So, it uses divide-and-conquer
paradigm.
First step is divide.
And to do this basically it
does it by partitioning.
So, it partitions the input
array into two subarrays around
an element we call the pivot --

Korean: 
아래 하위 배열에서 인자들은 x 보다 작거나 같습니다,  
위의 하위 배열에서 인자들은 x 보다 작거나 같습니다.
여러분이 입력 배열의 그림을 그린다면, 
이 분할 단계는 기본적으로 어떤 인자 x를 가집니다 
그리고 여기 모든 것은 분할 단계 후에 x 보다 작거나 같습니다. 
그리고 여기 모든 것은 x 보다 크거나 같습니다. 
이제 정복 단계는 매우 쉽습니다. 

English: 
-- such that elements in the
lower subarray are less than or
equal to x, are less than or
equal to elements in the upper
subarray.
If we draw a picture of the
input array, this partition step
basically takes some element x
and everything over here is less
than or equal to x after the
partition step and everything
over here is greater than or
equal to x.
And so now the conquer step is

English: 
pretty easy.
You just recursively sort the
two subarrays.
So, I recursively sort the
elements less than or equal to
x, I recursively sort the
elements greater than or equal
to x.
And then combine is then just
trivial.
Because once I have sorted the
things less than or equal to x,
then sorted the things greater
than or equal to x,
the whole thing is sorted.
So, there is nothing to do
really for the combine.
The key step in quicksort is
this partition step.
That is the thing that does all
of the work.
And so you can view quicksort
of just as recursive
partitioning.

Korean: 
여러분은 재귀적으로 두 하위 배열을 정렬했습니다. 
그래서, 저는 재귀적으로 x 보다 작거나 같은 인자들을 정렬합니다, 
저는 x 보다 크거나 같은 인자들을 
재귀적으로 정렬합니다. 
그리고 나서 결합은 사소한 것입니다. 
한번 제가 정렬한 것이 x 보다 작거나 같으면, 
정렬된 것은 x 보다 크거나 같습니다, 
모든 것은 정렬되었습니다. 그래서, 결합을 위해 정말 아무 것도 하지 않습니다. 
퀵정렬에서 핵심 단계는 이 분할 단계입니다. 
그것은 모든 일을 하는 단계입니다. 
그리고 여러분이 재귀 분할로써 
퀵정렬을 볼 수 있습니다. 

Korean: 
그것이 전부입니다. 합병 정렬이 재귀 합병이었던 것처럼, 
퀵정렬은 다른 길을 돌고 재귀 분할을 합니다. 
핵심은 선형 시간이라는 겁니다. 
저는 분할 서브루틴, (θ(n))을 의미합니다. 
그리고 여기 그것을 위한 수도 코드가 있습니다.
이것은 사실 책과 살짝 다릅니다. 
책에는 하나만 나와 있는데요. 사실, 책에 있는 것은 
다르지만 좋은 문제입니다, 

English: 
That's all it is.
Just as mergesort was recursive
merging, quicksort sort of goes
the other way around and does
recursive partitioning.
The key is the linear time,
by which I mean theta n,
partitioning subroutine.
And here are some pseudocode
for it.
This is actually slightly
different from the book.
The book has one.
In fact, there is a nice
problem in the book that has
even a different one,

English: 
but they are all basically the
same idea.
Partition (A,
p, q).
And what we are looking at,
at this step of the recursion,
is the subarray A from p to q.
And basically we pick a pivot,
which is we are going to just
pick as the first element of the
array A of p.
And the book,
just for your information,
uses A of q.
I use A of p.
It doesn't really matter.
And then we set an index to p
and then we have a loop.

Korean: 
그러나 그것들은 기본적으로 같은 생각입니다.
(A, p, q)를 분할하세요. 
그리고 우리가 이 재귀 단계에서 보는 것은 p부터 q까지의 하위 배열입니다. 
그리고 기본적으로 우리는 중심점을 고릅니다, 
그것은 p의 배열 A의 첫 번째 인자로써 우리가 
고르려고 하는 것입니다. 
그리고 여러분의 정보를 위해 책은 q의 A를 사용합니다. 
저는 p의 A를 사용합니다. 
그것은 정말 중요하지 않습니다. 그리고 우리는 p의 인덱스를 
만들고 루프를 가집니다.

English: 
This is the code.
Basically the structure of it
is a for loop with an "if"
statement in the middle.
And so the structure of the
algorithm of this partitioning

Korean: 
이것은 코드입니다. 기본적으로 그것의 구조는 
중간에 if문이 있는 for 루프 입니다. 
그리고 이 분할 단계의 알고리즘의 구조는 다음과 같습니다.

Korean: 
우리는 중심점을 첫 번째 인자로 합니다. 
여기 q가 있고 여기 p가 있습니다. 
이것은 변함이 없는 for 반복문이 되겠죠. 
그리고, 루프 실행 동안 언제든, 
저는 필수적으로 이미 x 보다 작거나 같은 i의 값을 올립니다. 
그리고 x 보다 크거나 같은  
j-1에서도요.
그리고 저는 남은 것에 대해 알지 못합니다. 
그리고 우리는 i가 p이고 j가 p+1 이라는 것에서 시작합니다. 
그것은 p+1에서 시작해서 모든 것은 
여기 x를 제외하고 알려져 있지 않습니다. 
그리고 생각은 그것이 이 변함없음을 유지할 것이라는 것입니다.

English: 
step looks as follows.
We set the pivot to be the
first element.
Here is p and here is q.
This is going to be our
invariant for the loop.
And, at any time during the
execution of a loop,
I essentially have some values
up to i which are already less
than or equal to x and then some
values that end at j minus 1
that are greater than or equal
to x.
And then I don't know about the
rest.
And so we start out with i
equal to p and j equal to p plus
1.
It starts out at p plus 1 so
that everything is unknown
except for x here.
And then the idea is that it is
going to preserve this

Korean: 
그리고 그것이 하는 방법은, 
우리가 루프를 돌면서, 그것은 j의 a를 봅니다 
그리고 그것이 x 보다 크거나 같은지 말합니다. 미안해요, 그것은 x 보다 작거나 같나요? 
그것이 x 보다 크거나 같다면 그것은 아무 것도 하지 않습니다. 
왜냐하면 무엇이 일어날 수 있나요? 
이것이 x 보다 크거나 같다면, 필수적으로 그것은 다음 반복 루프로 갑니다. 
그것은 이 경계로 가서 변함없음은 만족됩니다. 
모두 이것을 보았나요? 
네, 좋아요. 그러나 그것이 x 보다 작거나 같다면, 
저는 이 다음 인자가 x 보다 작거나 같은지 제가 불변을 유지하길
원하는지에 대한 문제를 가집니다. 
그리고 제가 이 경계를 옮기고 여기 이 인자를 바꾸어 보겠습니다. 
그것은 x 보다 크거나 같습니다, 
x 보다 작거나 같은 것이 이것을 가지고요, 
그렇게 함으로써 이 하위 배열의 크기가 증가되고 불변은 다시 유지됩니다. 
그것은 꽤 간단한 알고리즘입니다.

English: 
invariant.
And the way it does it is,
as we go through the loop,
it looks at a of j and says is
it greater than or equal to x?
Sorry, is it less than or equal
to x?
If it is greater than or equal
to x it does nothing,
because what can happen?
If this is greater than or
equal to x, essentially it just
goes to the next iterational
loop which moves this boundary
and the invariant is satisfied.
Does everybody see that?
Yeah, OK.
But if it is less than or equal
to x, I have got a problem if I
want to maintain the invariant
if this next element is less
than or equal to x.
And so what it does then is it
says oh, let me just move this
boundary and swap this element
here, which is greater than or
equal to x, with this one here
that is less than or equal to x,
thereby increasing the size of
this subarray and then the
invariant is satisfied again.
It is a fairly simple

English: 
algorithm.
And it is actually a very tight
and easy algorithm.
That is one reason that this is
such a great piece of code
because it is very efficient.
Now, in principle,
the running time for this on n
elements is order n.
Because I am basically just
going through the n elements and
just doing a constant amount of
work and then just a constant
amount of work outside.
This is a clever piece of code.
In fact, in principle partition
is easy, right?
If I weren't worrying about
doing it in place,
it is really a pretty easy
thing to do.
I take an element and just
compare every other element with
it.
I throw one into one bin and
one into the other.
That is clearly linear time.

Korean: 
그리고 그것은 사실 매우 타이트하고 쉬운 알고리즘입니다. 
이것이 훌륭한 코드인 하나의 이유입니다  
왜냐하면 그것은 매우 효율적이니까요.
그러니까 이론상으로 인자가 n개 일때
러닝타임은 θ(n_ 입니다. 
제가 기본적으로 n 인자를 통해 가고 
정수 양의 일을 하기 때문입니다. 
이것은 똑똑한 코드입니다. 
사실, 이론적으로 분할은 쉽습니다, 그렇죠? 
만약 제가 그것을 하는 것에 대해 걱정하지 않는다면,  
그것은 하기 정말 쉬운 것입니다.
저는 인자를 가지고 그것을 다른 모든 인자들과 비교합니다. 
저는 하나를 쓰레기 통에 던지고 다른 것을 다른데 던집니다. 
그것은 명백히 선형 시간입니다.

Korean: 
그러나 종종 여러분이 찾는 것은 여러분이 그것을 할 수 있기 때문에 
그 방법이 이론적으로 여러분에게 좋은 코드를 줄 것이라는 것입니다. 
그리고 이것은 여러분이 
하도록 허락하는 좋은 코드입니다. 
그리고 그것은 이것이 특별히 좋은 알고리즘인 이유입니다, 
왜냐하면 상수들이 좋기 때문입니다. 
그래서, 네, 우리가 점진적인 분석을 할 때 우리는 상수들을 무시하는 경향이 있지만, 
우리가 실제로 코드를 만들 때 우리는 상수들에 대해 신경 써야 합니다.
그러나 여러분이 상수 보다 더욱 많이 생각해야 하는 것은 
전반적으로 그것이 빠른 알고리즘인지 아닌지 입니다. 
이것의 예를 살펴 봅시다. 
저는 여기서 그것을 할 것입니다. 요지를 이해해 봅시다. 
여기 제가 만들었던 같은 배열이 있습니다. 

English: 
But often what you find is that
just because you can do it that
way theoretically doesn't mean
that that is going to end up
giving you good code.
And this is a nice piece of
code that allows you to do it in
place.
And that is one reason why this
is a particularly good
algorithm, because the constants
are good.
So, yes, when we do asymptotic
analysis we tend to ignore the
constants, but when you're
actually building code you care
about the constants.
But first you care much more
than just about the constants,
is whether overall it is going
to be a fast algorithm.
Let's go through an example of
this, I guess I will do it over
here, just so we get the gist.
Here is a sample array that I
have created out of hallcloth.

English: 
And here we are going to set x,
the pivot, to be 6.
Let's look to see how this
algorithm works.
So, i starts out here and j
starts out here if we
initialize.
And what we do is start
scanning right,
essentially that code is
scanning right until it gets
something which is less than or
equal to the pivot.
It keeps going here until it
finds, j keeps incrementing
until it finds something that is
less than or equal to the pivot.
And, in that case,
it is the number 5.
Then it says we will swap these
two things.
And it does that and we get 6,
5, 13, 10, 8,
3, 2, 11.
And meanwhile now i gets
incremented and j continues

Korean: 
그리고 여기서 우리는 x, 중심점을 6으로 합니다. 
이 알고리즘이 어떻게 동작하는지 봅시다. 
i는 여기서 시작하고 j는 여기서 시작합니다 우리가 초기화하면요. 
그리고 우리가 하는 것은 옳게 스캐닝하기 시작하는 것입니다, 
필수적으로 그 코드는 
그것이 중심점 보다 작거나 같은 것을 얻을 때까지 옳게 스캐닝합니다. 
그것은 찾을 때까지 계속합니다, 
j는 그것이 중심점 보다 작거나 같은 것을 찾을 때까지 계속 증가합니다.
그리고, 그 케이스에서, 
그것은 숫자 5 입니다. 그리고 그것은 우리가 이 두 개를 바꿀 것이라고 말합니다. 
그리고 그것은 그것을 하고 우리는   
6, 5, 13, 10, 8, 3, 2, 11을 얻습니다.
그리고 그러는 동안 이제 i는 증가하고 j는 계속 됩니다. 

Korean: 
그리고 이제 우리는 우리가 중심점 보다 작거나 같은 것을  
얻을 때까지 옳게 스캐닝을 계속합니다.
이 경우에 그것은 3 입니다. 
우리는 3과 5를 바꾸고 6, 3, ... 등을 얻습니다. 
그리고 이제, 이 단계에서 우리는 i를 증가시키고, 우리는 여기서 j를 시작합니다.
그리고 이 경우에, 
즉시, 우리는 x 보다 작거나 같은 것을 가지고 있고,  
우리는 이 두 개를 바꿉니다.
저는 그것을 날려버렸습니다, 그렇죠? 웁스. 
제가 무엇을 했나요? 
제가 여기서 잘못 바꿨네요
그렇죠? 
여기서요? i+1을 바꿨어야 했네요
그렇죠?

English: 
where it left off.
And so now we keep scanning
right until we get to something
that is less than or equal to
the pivot.
In this case it is 3.
We swap 3 and 5 and get 6,
3, etc.
And now, at this step we
increment i, we start j out
here.
And in this case,
right off the bat,
we have something which is less
than or equal to x,
so we swap these two.
I blew it, didn't I?
Oops.
What did I do?
I swapped the wrong thing,
didn't I, here?
Ah-ha.
That is why I am not a
computer.
Good.
We should have swapped this
guy, right?
Swapped i plus 1,

English: 
right?
This was i.
We swap i plus 1,
good.
So, that's all wrong.
Let's swap the right things.
Now we have 6,
5, 3, 10, 8,
13, 2, 11.
That even corresponds to my
notes for some strange reason.
This is i and now this is j.
And now when I look,
I immediately have something
that is less than or equal to
the pivot.
We swap this and i plus 1,
so now we have 6,
5, 3, 2, 8, 13,
10, 11.
And we, at that point,
increment i to here.

Korean: 
이것은 i였습니다.
i+1과 바꿔야죠, 좋아요. 
그래서, 그것은 모두 틀렸습니다. 옳은 것을 바꿔봅시다. 
이제 우리는 6, 5, 3, 10, 8, 13, 2, 11를 가집니다. 
그것은 어떤 이상한 이유인지 제 노트와 일치합니다. 
이것은 i이고 이제 이것은 j입니다. 
그리고 이제 제가 볼 때, 저는 즉시 
중심점 보다 작거나 같은 것을 가집니다.
우리는 이것과 i+1을 바꿉니다, 
그래서 이제 우리는 6, 5, 3, 2, 8, 13, 10, 11을 가집니다. 
그리고 우리는, 이 점에서, i를 여기로 증가시킵니다. 

English: 
And we have j now going here
and j runs to the end.
And the loop terminates.
When the loop terminates there
is one less swap that we do,
which is to put our pivot
element in the middle between
the two subarrays.
Here we swap this one and this
one, and so that gives us then
2, 5, 3, 6, 8,
13, 10, 11.
And this is the pivot.
And everything over here is
less than or equal to the pivot.
And everything over here is
greater than or equal to the
pivot.
OK, so the quicksort routine.
Once we have this partition

Korean: 
그리고 우리는 이제 여기로 가는 j를 가집니다 j는 끝까지 갑니다 
그리고 루프는 종료합니다. 루프가 종료될 때 
한 번 바꿉니다, 두 하위 배열 간의 중간에
우리의 중심점(pivot) 인자를 넣는 거죠. 
여기서 우리는 이것과 이것을 바꿉니다, 
그리고 그것은 우리에게 2, 5, 3, 6, 8, 13, 10, 11을 줍니다. 
그리고 이것은 중심점입니다. 
그리고 여기 모든 것은 중심점 보다 작거나 같습니다. 그리고 여기 모든 것은 
중심점 보다 크거나 같습니다. 
네, 그래서 퀵 정렬 루틴입니다. 우리가 한번 이 분할 루틴을 하면, 

Korean: 
퀵 정렬은 쓰기 매우 쉬운 코드입니다. 
제가 여기서 i를 리턴한다고 말했어야 했는데 말이죠, 네? 
여러분은 중심점을 리턴해야 합니다. 
여기서 저는 i를 리턴해야 합니다 왜냐하면 
중심점 인자가 어디 있는지 알길 원하기 때문입니다. 미안해요.
저는 제 코드를 연결할 것입니다. R은 (A, p, q)의 분할을 얻고 

English: 
routine, quicksort is a pretty
easy piece of code to write.
I should have said return here
i, right?
You have got to return with the
pivot.
Here I have got to return i
because we want to know where
the pivot element is.
Sorry.
I will plug in my code.
r gets partition of (A,

English: 
p, q) and then we quicksort (A,
p, r-1) and quicksort of (A,
r+1, q).
And that is it.
That's the code.
The initial call is quicksort
of (A, 1, n).
Because once we partitioned,
we just have to quicksort the
two portions,
the left and right portions.
Just the boundary case is
probably worth mentioning for a
second.
If there are zero or one
elements, that is basically what
can possibly happen here,
is that I get zero or one
elements here.
Then the point is there is
nothing to do because the array
is sorted, either because it is
an empty array or because it
only has one element.
One of the tricks to making
quicksort go fast,

Korean: 
우리는 (A, p, r-1)과 (A, r+1, q)를 퀵정렬 합니다. 
그게 전부입니다. 
그것이 코드 입니다. 초기 호출은 (A, 1, n)의 퀵정렬입니다. 
우리가 한번 분할하면, 
우리는 두 부분으로 퀵정렬해야 합니다, 
왼쪽과 오른쪽 부분으로요. 
경계 부분은 아마 잠깐 언급할 가치가 있는 것 같군요. 
0이나 1 인자가 있으면, 그것은 기본적으로 여기서 일어날 수 있는 것입니다, 
제가 0이나 1 인자를 여기서 얻으면요. 
그러면 핵심은 할 것이 아무것도 없다는 것입니다
왜냐하면 배열은 정렬되었기 때문입니다. 
그것은 빈 배열 또는 오직 하나의 인자만을 가지고 있는 배열이기 때문입니다.
퀵정렬을 빠르게 만드는 방법 중 하나는, 

English: 
as one tunes this,
is to, in fact,
look at having a special
purpose sorting routine for
small numbers of elements.
For example,
if you get down to five
elements having some straight
line piece of code that knows
how to sort five elements
sufficiently as opposed to
continuing to go through
recursion in order to accomplish
that.
And there are a variety of
other things.
This is a tail recursive code,
and so you can use certain tail
recursion optimizations.
And there are a variety of
other kinds of optimizations
that you can use to make this
code go fast.
So, yeah, you can tune it up a
bit beyond what is there,
but the core of it is this
efficient partitioning routine.
That is the algorithm.
It turns out that looking at

Korean: 
이것이 조율할 때, 사실, 
인자들의 작은 수들을 위해 특별한 정렬 루틴 목적을 갖는 것을 보는 것입니다. 
예를 들어, 
만약 여러분이 직선 코드를 가지고 있는 5 인자들을 가지면, 
그것은 그를 성취하기 위해 순환을 통해 계속하는 것과 반대로 
충분히 5 인자들을 정렬하는 
방법을 알고 있습니다. 
그리고 많은 다른 것들이 있습니다. 
이것은 꼬리 재귀 코드 입니다, 그리고 여러분은 꼬리형 재귀 최적화를 사용할 수 있습니다.
그리고 여러분이 이 코드를 빠르게 하기 위해 사용할 수 있는 
다른 종류의 많은 최적화들이 있습니다.
네, 여러분은 거기 무엇이 있는지 그것을 조율할 수 있습니다, 
그러나 그것의 핵심은 이 효율적인 
분할 루틴입니다. 
그것이 알고리즘입니다. 그것이 얼마나 빨리 도는지 

English: 
how fast it runs is actually a
little bit challenging.
In the analysis,
we are going to assume that all
elements are distinct.
It turns out that this
particular code does not work
very well when you have repeated
elements, but Hoare's original
partitioning routine is actually
more efficient in that case if
there are duplicates in what you
are sorting.
And I encourage you to look at
that.
It has a much more complicated
invariant for partitioning
routine, but it does a similar
kind of thing.
It's just a bit more
complicated.
If they weren't all distinct,
there are things you can do to
make them distinct or you can
just use this code.
The easiest thing to do is just

Korean: 
보는 것은 사실 약간 어려운 일입니다. 
분석적으로, 우리는 모든 인자들이 
서로 다른 값을 갖는다고 가정할 것입니다. 
이 특별한 코드는 여러분이 인자들을 반복할 때 매우 잘 동작하지 않을 것입니다, 
그러나 Hoare의 원조 분할 루틴은 사실 이 케이스에서 더 효율적입니다 
여러분이 정렬하려고 하는 것에서 복사본이 있으면요.
그리고 저는 여러분이 그것을 보도록 독려할 것입니다. 
그것은 분할 루틴을 위한 더욱 복잡한 불변을 가지고 있습니다, 
그러나 그것은 비슷한 일을 합니다. 
그것은 약간 더 복잡할 뿐입니다. 
그것들이 모두 다르지 않다면, 
여러분이 그것들을 다르게 구분 짓는 일을 할 수 있거나 
여러분은 이 코드를 그냥 사용할 수 있습니다. 가장 쉬운 방법은 

Korean: 
Hoare의 원조 코드를 사용하는 것입니다 왜냐하면 그것은 그것들이 다르지 않을 때 
매우 잘 작동하기 때문입니다.
그러나 이것은 이해하기 약간 더 쉽습니다. T(n)이 n 인자에서 
worst-case의 러닝 타임이라고 해 봅시다. 
그리고 무엇이 worst-case인가요? 
퀵정렬에서의 worst-cae는 무엇이 되어야 하나요? 
좋습니다. 만약 여러분이 항상 중심점을 고르고
모든 것이 크거나 또는 모든 것이 작으면, 
여러분은 배열을 매우 잘 분할 하지 않을 것입니다 
그리고 그것은 언제 일어납니까? 
그것이 일어나게 만드는 원래의 입력은 무엇입니까? 

English: 
use Hoare's original code
because that works pretty well
when they are nondistinct.
But this is a little bit easier
to understand.
Let's let T(n) be the
worst-case running time on n
elements.
And so what is the worse-case?
What is the worse-case going to
be for quicksort?
That's right.
If you always pick the pivot
and everything is greater than
or everything is less than,
you are not going to partition
the array very well.
And when does that happen?
What does the original input
look like that makes that
happen?

Korean: 
그것이 이미 정렬되었거나 역으로 정렬 되었다면요.
그래서, 입력이 정렬되었거나 역으로 정렬 되었다면요. 
그것은 사실 이해해야 하는 중요한 것입니다, 
왜냐하면 가장 일반적인 정렬하는 것은 이미 정렬된 것이고,  
놀랍게도, 또는 거의 정렬된 
것이기 때문입니다.
그러나 종종 그것은 정렬되고 누군가 그것이 정렬되었다고 확신하길 원합니다. 
자, 그것이 정렬되었는지 확인하기 보다  
그것을 다시 정렬해 봅시다.
그리고, 그 케이스에서,
각 분할의 한 면은 아무 인자도 가지지 않습니다. 그리고 우리는 그것을 위한 재귀가 무엇인지 쓸 수 있습니다. 
우리는 T(n)을 가집니다. 

English: 
If it is already sorted or
reverse sorted.
So, if the input is sorted or
reverse sorted.
That is actually kind of
important to understand,
because it turns out the most
common thing to sort is
something that is already
sorted, surprisingly,
or things that are nearly
sorted.
But often it is just sorted and
somebody wants to make sure it
is sorted.
Well, let's just sort it again
rather than checking to see if
it is sorted.
And, in those cases,
one side of the partition of
each partition has no elements.
Then we can write out what the
recursion is for that.
We have T(n).

Korean: 
만약 한 면이 아무 인자도 가지지 않는다면, 그 면에서 T(0)을 가질 것입니다.
그리고 다른 면에서 우리는 T(n-1)을 가질 것입니다. 
우리는 이를 위한 재귀를 쓸 것입니다. 
한 면은 아무 인자도 가지지 않습니다.
다른 면은 n-1 인자들을 가집니다. 
그리고 분할이나 모든 부기 등은
θ(n) 입니다. T(0)이 무엇입니까? 
T(0)이 무엇이죠? 그것은 점진적으로 무엇입니까? 
그것은 상수, θ(1) 입니다. .
그것은 θ(1) + T(n-1) + θ(n) 입니다. 
자, θ(1)은 θ(n)에 흡수될 수 있습니다, 
그래서 이것은 T(n-1) + θ(n) 입니다.

English: 
If one side has no elements,
we are going to have T(0) on
that side.
And on the other side we are
going to have T(n-1).
We are just writing out the
recursion for this.
One side has no elements.
The other side has n-1
elements.
And then partitioning and all
the bookkeeping and so forth is
order n.
What is T(0)?
What is T(0)?
What is that asymptotically?
It's a constant,
order 1.
That is just order 1 + T(n-1) +
order n.
Well, the order 1 can be
absorbed into the order n,
so this is really just saying
it is T(n-1) + order n.

Korean: 
그리고 그것은 무엇과 같습니까? 그것은 θ(n^2) 입니다. 
왜 그것이 θ(n^2) 입니까? 그것은 등차 급수 입니다. 
사실, 우리가 삽입 정렬을 위해 했던 것처럼요. 
삽입 정렬을 위한 것과 같은 것은 등차 급수입니다.
모든 일을 따라서 우리는 퀵정렬이라는 알고리즘을 가집니다, 
그리고 그것은 삽입 정렬 보다 더 빠르지 않습니다. 
그럼에도 불구하고, 저는 그것이 좋은 알고리즘이라고 말했습니다. 
그것이 좋은 알고리즘인 이유는 그것의 평균 시간이, 

English: 
And what is that equal to?
That is order n^2.
Why is that order n^2?
It is an arithmetic series.
Actually, just like we got for
insertion sort.
Just like for insertion sort it
is an arithmetic series.
Going through all that work and
we have an algorithm called
quicksort, and it is no faster
than insertion sort.
Nevertheless,
I said it was a good algorithm.
The reason it is a good
algorithm is because its average

English: 
case time, as we are going to
see, is very good.
But let's try to understand
this a little bit more just so
that we understand the
difference between what is going
to happen in the average case
and what is going to happen in
the worse-case.
Let's draw a recursion tree for
this for T(n) = T(0) + T(n-1) +
and I will make the constant
explicit for cn.
So, we get an intuition of what
is going on.
Some constant times n.
And then we have T(n) is equal
to, and we write it with the
constant part here,
cn, and then T(0) here,
and then T(n-1) here.
Now, I know that all you folks
are really fast and want to jump
immediately to the full-blown
tree.
But, let me tell you,

Korean: 
우리가 보게 되겠지만, 매우 좋기 때문입니다.
그러나 이것을 더 이해해 보려고 노력해 봅시다 
그래서 우리는 average-case에서 무엇이 일어날 것 인지와 worst-case에서 무엇이 일어날 것 인지 
간의 차이를 이해 합니다. 
이를 위한 재귀 트리를 그려 봅시다. 
T(n) = T(0) + T(n-1) + 그리고 저는 cn을 위해 상수를 분명하게 할 것입니다. 
그래서, 우리는 무엇이 진행되는지에 대한 직관을 얻습니다. 
어떤 정수 곱하기 n 입니다. 
그리고 나서 우리는 T(n) 을 가집니다, 그리고 우리는 그것을 여기서 정수 부분 
cn과 함께 씁니다, 그리고 여기 T(0)이 있고 
여기 T(n-1)이 있습니다. 이제 저는 여러분 모두 정말 빠르고 
즉시 완전한 트리로 점프하고 싶다는 것을 압니다.
그러나, 여러분에게 말할 것이 있습니다, 

English: 
my advice is that you spend
just a couple of minutes writing
it out.
Since the tree grows
exponentially,
it only costs you a constant
overhead to write out the small
cases and make sure that you
have got the pattern that you
are developing.
So, I am going to go one more
step.
Here we have T(0) and now this
becomes c(n-1) and now we have
another T(0) over here and
T(n-2).
And we continue that,
dot, dot, dot.
That is all equal to cn with a
T(0) here, c(n-1) with a T(0),
c(n-2), T(0) here,
and that goes all the way down

Korean: 
제 조언은 여러분이 그것을 쓰는데 몇 분이 걸린다는 것입니다. 
트리는 지수적으로 증가하기 때문에, 
작은 케이스들을 쓰는데 정수의 오버헤드가 들고 
여러분이 발전시키는 패턴을 가져야 한다는 것을 
확실히 해야 합니다. 
그래서, 저는 한 단계를 더 할 것입니다 
여기서 우리는 T(0)을 가지고 이제 이것은 c(n-1)이 되었고 
이제 우리는 여기서 또 다른 T(0)과 T(n-2) 을 가집니다. 
그리고 우리는 그것을 계속합니다, · · · 
그것은 여기 T(0)과 함께 cn과 모두 같습니다, 
여기 T(0), c(n-2), T(0)과 함께 c(n-1)과 같습니다, 그리고 그것은 

English: 
until we end up with T(1) down
here.
What is the height of this tree?
What is the height of the tree
here?
Yeah, n.
Good.
Because every step we are just
decrementing the argument by 1.
So, the height is n.
To analyze this,
let's first add up everything
that is here.
Just so we understand where
these things are coming from,
this is just theta of the
summation of k equals 1 to n of

Korean: 
우리가 여기서 T(1)을 끝낼 때까지 계속 내려갑니다.
이 트리의 높이는 무엇입니까? 
이 트리의 높이는 무엇입니까? 
네, n입니다. 좋아요. 
우리가 인자를 1로 감소시켰던 모든 단계들 때문입니다. 
그래서, 높이는 n입니다. 이것을 분석하기 위해, 
여기 있는 모든 것을 먼저 더합시다. 
그래서 우리는 이것들이 어디서 왔는지 이해합니다, 
이것은 k의 합의 θ(theta)입니다. 

Korean: 
그것은 저기 안에 있는 것입니다. 
그리고 그것은 θ(n^2)와 같습니다. 그것은 알고리즘의 열(series)이 온 곳입니다. 
그래서, 그것은 θ(n^2) 입니다. 
그리고 여기 이 모든 것들은 모두 θ(1) 입니다.
그리고 그것들 중 얼마나 많이 거기에 있습니까? n개의 θ(1)가 있는 거죠. 
그래서, 총 양은 T(n) = θ(n) + θ(n^2) = θ(n^2) 입니다. 

English: 
k, actually of ck.
That is what is in there.
And that is equal to order n^2.
That is where our algorithmatic
series is coming from.
So, that is Theta(n^2).
And then all of these things
here are all Theta(1).
And how many of them are there?
There are n Theta(1)'s.
So, the total amount is T(n) =
Theta(n) + Theta(n^2) =

English: 
Theta(n^2).
Just to see what the structure
is in terms of the recursion
tree, it is a highly unbalanced
recursion tree.
Now I am going to do something
that I told you should never do,
which is we are going to be do
a best-case analysis.
This is for intuition only.
And, in general,
we don't do best-case analyses.
It doesn't mean anything,
unless we get some intuition
for it maybe.
But basically it means nothing
mathematically because it's
providing no guarantee.

Korean: 
재귀 트리의 관점에서 무슨 구조인지 알기 위해, 
매우 불균형한 재귀 트리 입니다. 
이제 저는 제가 여러분에게 전혀 하지 말아야 한다고 
말한 것을 해 볼 것입니다. best-case에 대해 다뤄볼 건데요. 
이것은 단지 직관을 위한 것뿐입니다. 
그리고, 일반적으로, 우리는 best-case 분석을 하지 않습니다. 
그것은 우리가 그것을 위한 어떤 직관을 가지지 않는다면 아마 아무 것도 의미 하지 않습니다. 
그러나 기본적으로 그것은 수학적으로 아무 것도 의미하지 않습니다. 
왜냐하면 그것은 아무 보장도 제공하지 않기 때문입니다. 

English: 
And so this is intuition only.
If we are really lucky what
happens for partition?
What is going to be the lucky
case?
Yeah, it splits right in the
middle.
Which is essentially --
-- n/2 : n/2.
It is really (n-1)/2 :
(n-1)/2, but we're not going to
worry about the details because
we're only doing intuition for
the best-case because best-case

Korean: 
이것은 단지 직관입니다 
만약 우리가 정말 운이 좋다면 분할을 위해 무엇이 일어나죠? 
운 좋은 케이스는 무엇일까요? 
네, 그것은 중간에서 나누는 것입니다. 
필수적으로,
n/2 : n/2 입니다. 그것은 정말로 (n-1)/2 : (n-1)/2 이지만, 
우리는 자세한 것에 대해 걱정하지 않아도 됩니다. 
왜냐하면 우리는 best-case에 대한 직관만을 하려고 하니까요 

Korean: 
왜냐하면 best-cae는 우리가 원하는 것이 아닙니다.
그것이 일어나면, 제가 얻는 재귀는 무엇이죠? 
그것이 항상 중간에서 정확하게 나눈다고 가정해 보세요, 그러면 무슨 일이 일어납니까? 
여러분은 분할과 부기를 위해 T(n) = 2T(n/2) + θ(n)을 얻습니다. 
그리고 그 재귀의 답은 무엇입니까?  
답은 n log n 입니다.
그것은 합병 정렬 재귀와 같습니다.
그것은 마스터 정리의 어떤 케이스 이지요? 
케이스 2인가요? N의 로그 2의 2 제곱이 
1이기 때문에, 그것은 같습니다, 

English: 
is not what we want.
If that happened,
what is the recurrence I get?
Imagine it split it exactly in
the middle every time,
then what happens?
You get T(n) = 2T(n/2) + order
n for partitioning and
bookkeeping.
And what is the solution of
that recurrence?
That is n log n.
That is the same as the merge
sort recurrence.
It is which case of the master
theorem?
Case 2, right?
Because n to the log base 2 of
2 is n to the 1,
it is the same,

English: 
so we tack on the extra log n.
Case 2 of the master theorem.
That is pretty good.
That says that in the best-case
quicksort is going to do well.
How about let's suppose the
split is always let's say 1/10 :
9/10, 1/10n :
9/10n.
In that case,
are we lucky or are we unlucky?
I mean, if the split is really
skewed, we clearly are going to

Korean: 
그래서 우리는 나머지 log n으로 갑니다. 마스터 정리의 케이스 2 입니다. 
그것은 매우 좋습니다. 그것은 best-case인 
퀵정렬에서 그것이 잘 동작할 것이라고 말합니다. 분할이 항상 
1/10 : 9/10, 1/10n : 9/10n 이라고 가정하면 어떨까요? 
그 경우에, 
우리는 운이 좋은 걸까요 나쁜 걸까요? 
분할이 정말로 치우친다면, 우리는 명백히 

English: 
be unlucky, right,
because then it's,
say, 1 to n.
If it is really in the middle
it is n log n.
What do you suppose it is if it
is 1/10 : 9/10?
Is that lucky or unlucky?
We will have a little democracy
here.
Who thinks that that is a lucky
case?
It is going to be fast running
time.
And who thinks it is an unlucky
case?
OK, so we have some brave
souls.
And who didn't vote?
Oh, come on.
Come on.
It is always better,
by the way, to say yes or no
and be right or wrong,
because then you have some
emotional commitment to it and
we will remember better,
rather than just sitting and
being quiet.
You don't manipulate your own
emotions well enough to remember
things well.
Those people who voted win over
the people who don't vote,
whether they are right or
wrong.

Korean: 
운이 나쁩니다, 왜냐하면 그것은 1의 n 이거든요. 
그것이 정말 중간에서이면 
그것은 n log n 입니다. 그것이 1/10 : 9/10 이면 여러분은 무엇을 해야 합니까? 
그것은 운이 좋을까요 나쁠까요?
우리는 여기서 작은 민주주의를 가질 것입니다. 
그것이 운이 좋은 경우라고 생각하는 학생 있나요? 
그것은 빠른 러닝 타임이 될 것입니다. 
그것이 운이 나쁜 경우라고 생각하는 학생 있나요? 
네, 그래서 우리는 용감한 영혼들을 가지고 있군요 
그리고 투표하지 않은 학생 있나요? 오 안됩니다.
그런데, 예 아니오 라고 말하거나 
옳다 틀리다 라고 말하는 것은 항상 더 좋습니다
왜냐하면 여러분이 그것에 대해 감정적으로 전념하기 때문에 우리는 더 잘 기억할 수 있거든요
가만히 앉아있는 것 보다도요. 
여러분은 기억을 충분히 잘 할 만큼 여러분 
자신의 감정을 조작하지 않습니다. 
그들이 맞든 틀리든 투표한 학생은 
투표하지 않은 학생을 이깁니다. 

English: 
Well, let's take a look.
Here is the recurrence.
T(n) = T(1/10n) + T(9/10n) +
Theta(n).
And we will assume that this
part here is less than or equal
to some cn in order to analyze
it.
We will just do a recursion
tree for this and see.
Here is a recursion tree.
We have T(n) = cn,
T(1/10n), T(9/10n).
Now we have again cn at the
top.
This gets complicated,
right?

Korean: 
자, 봅시다. 여기 재귀가 있습니다. 
T(n) = T(1/10n) + T(9/10n) + θ(n).
그리고 우리는 그것을 분석하기 위해 여기 이 부분이 
어떤 cn 보다 작거나 같다고 가정할 것입니다. 
재귀 트리를 이용해보죠. 
여기 재귀 트리가 있습니다.
우리는 T(n) = cn, T(1/10n), T(9/10n) 을 가집니다. 
이제 우리는 위에서 다시 cn을 가집니다. 
이것은 복잡해집니다, 그렇죠? 

English: 
This is 1/10cn.
Now, over here we have 1/10.
And then we are plugging it
into the recursion again,
so we now get T(1/100n) and
over here we get T(9/100n).
And over here we have now
9/10cn.
And that gives us T(9/100n)
again.
And here we get T(81/100n).
And we keep going on.
That is equal to cn,
1/10cn here.

Korean: 
이것은 1/10cn 입니다. 이제, 여기서 우리는 1/10을 가집니다. 
그리고 우리는 그것을 다시 재귀에 연결합니다, 
그래서 우리는 이제 T(1/100n)을 얻고 여기서 T(9/100n)를 얻습니다. 
여기서 우리는 이제 9/10cn을 가집니다. 
우리는 여기서 다시 T(9/100n)을 줍니다.
그리고 여기서 우리는 T(81/100n)을 얻습니다 
계속해봅시다.

English: 
Down this way we have 1/100cn.
And that keeps going down until
we get to order 1 down here.
And over here we have 9/10cn.
And here, let's see,
this is 9/100cn and this is now
9/100cn and this is 81/100cn.
And these things keep going
down until they get down to
order 1.
But the leaves are not all at
uniform depth here,
right?
This side is way further up
than this side,
right?
Because here we are only going
down by 9/10 each time.
So, in fact,
what is the length of this path

Korean: 
 
393
00:35:08,268 --> 00:35:16,931
그것은 여기 1/10cn, cn과 같습니다.
여기서 우리는 1/100cn을 가집니다.
그리고 계속 아래로 내려갑니다
여기서 우리가 1을 얻을 때까지요. 
그러나 잎들은 전혀 여기 단일 깊이에 없습니다, 그렇죠? 
이 면은 이 면 보다 위 입니다, 
그렇죠? 
여기서 우리는 각 시간 9/10에 의해 내려가기 때문입니다. 
그래서, 사실 여기서 이 길의 길이는 무엇이죠?

English: 
here?
What is the length of this path
down to this,
if I take the left most spine?
Somebody raise there hand.
Yeah?
Log base 10 of n.
Because I am basically cutting
down by a factor of 10 each
time.
And how long does it take me to
reduce it to 1?
That is the definition,
if you will,
of what a log is,
log base 10.
What is this one?
What is this path going that
way?

Korean: 
여기로 이 길의 길이는 무엇이죠? 
만약 제가 왼쪽을 가진다면요, 
누가 저기서 손을 들었군요. 네? 
로그 10의 n입니다. 제가 기본적으로 각 시간 10의 
요소에 의해 자르고 있기 때문입니다. 
그리고 그것을 1로 줄이기 위해 얼마나 걸리죠? 
그것은 정의 입니다, 
지수가 10인 로그죠. 
이것은 무엇이죠? 이 길은 그 방법으로 갑니까? 

Korean: 
N의 로그 입니다 로그 10/9의 n입니다. 우리가 각 시간 9/10으로 내려가고 있기 때문입니다. 
다시 한번, 필수적으로 n의 정의 입니다. 
그리고 그것들 사이의 모든 것은 
로그 10의 n 그리고 로그 10/9의 n 사이의 어딘가에 있습니다. 
그래서, 모든 것은 거기 사이에 있습니다. 
이제 제가 할 수 있는 것은 우리가 합병 정렬에서 했던 것처럼 속임수를 쓸 것입니다. 
총 단계의 비용을 더함으로써 
이것의 값을 구해보면서요. 
그것은 cn입니다. 다음 단계의 비용은 무엇이죠? 
cn입니다. 
그리고 다음 단계의 비용은 무엇이죠? 
cn입니다. 모든 단계에서 우리는 같은 양의 일을 합니다. 
그리고 우리는 모든 같은 길을 내려 갑니다.

English: 
Log of n. Log base 10/9 of n.
Because we're going down by
9/10 each time.
Once again, essentially the
definition of n.
And everything in between there
is somewhere between log base 10
of n and log base 10/9 of n.
So, everything is in between
there.
Now what I can do is do the
trick that we did for mergesort
in looking at what the
evaluation of this is by adding
up what is the cost of the total
level.
That is just cn.
What is the cost of the next
level?
cn.
And what is the cost of the
next level?
cn.
Every level we are still doing
the same amount of work.
And we take that all the way

English: 
down.
And the last levels --
Eventually we hit some point
where it is not equal to cn
where we start getting things
that are less than or equal to
cn because some of the leaves
start dropping out starting at
this level.
Basically this part is going to
be log base 10 of n,
and then we start getting
things that are less than or
equal to cn, and so forth,
until finally we get to add it
all up.
T(n) is going to be less than
or equal to cn times,
well, what is the longest that
this could possibly be?
Log base 10/9 of n.
Plus we have all of the leaves
that we have to add in,
but all the leaves together add

Korean: 
결국 우리는 cn 보다 작거나 같은 것을 시작하는 곳에서 
cn과 같지 않은 곳에서 어떤 점을 치게 됩니다. 
왜냐하면 어떤 잎들은 이 레벨에서 떨어지기 시작하기 때문입니다. 
기본적으로 이 부분은 로그 10의 n이 될 것입니다, 
그리고 나서 우리는 cn 등과 같은 것보다 작거나 같은 것을 
얻기 시작합니다, 
우리가 그것은 모두 얻을 때 까지요. 
T(n)은 cn 곱하기 이것 보다 작거나 같을 것입니다, 
자, 이것은 가장 길게 무엇이 될 수 있을까요? 
로그 10/9의 n 입니다. 우리가 더해야 하는 모든 잎들을 더합니다, 
그러나 모든 잎들은 θ(n)으로 함께 더해질 것입니다.

Korean: 
모든 잎들은 θ(n)으로 더해집니다, 
우리는 + θ(n)을 가집니다. 그리고 이것은 얼만큼 입니까? 
만약 제가 이것들을 모두 더한다면, 이것은 점진적으로 무엇입니까? 
그것은 n log n 입니다. 그래서 T(n)은 사실 n log n 으로 제한됩니다. 
우리는 운이 좋습니다. 
추측한 운 좋은 사람들이 맞았군요. 1/10 : 9/10 은  
점진적으로 50 : 50 이 됩니다.
그리고, 사실, 
우리는 여기서 이것을 봄으로써
사실 T(n)이 cn 로그 10의 n + θ(n) 이라는 것을 알 수 있습니다. 
그리고 T(n)은 점진적으로 n log n 입니다. 

English: 
up to just order n.
All the leaves add up to order
n, so we have + Theta(n).
And so this is how much?
If I add all of this together,
what is this asymptotically?
That is n log n.
So, T(n) is actually bounded by
n log n.
We are lucky.
Those people who guessed lucky
were right.
A 1/10 : 9/10 split is
asymptotically as good as a 50 :
50 split.
And, in fact,
we can lower bound this by just
looking at these things here and
discover that,
in fact, T(n) is lower bounded
by cn log base 10 of n + order
n.
And so T(n) is lower bounded by
also asymptotically n log n.

English: 
So, T(n) is actually Theta(n lg
n).
Now, this is not really proof.
I generally recommend that you
don't do this kind of thing to
do a proof.
This is a good intuition of a
recursion tree.
The way you prove this is what?
Substitution method.
Good.
What you do is use this to get
your guess and then use
substitution method to prove
that your guess is right.
It is too easy to make mistakes
with this method.
It is very easy to make
mistakes.
With the substitution method it
is harder to make mistakes
because there is just algebra
there that you are cranking
through.
It is easier to verify rather
than dot, dot,
dots and trees that you drew
improperly and wrote in wrong
amounts and so forth.
OK?
So, this is n log n.
That's pretty good.
It is order n log n.
And we are lucky.

Korean: 
그래서, n log n 은 사실 θ(nlg n) 입니다.
이제, 이것은 정말로 증명이 아닙니다. 
저는 일반적으로 여러분이 이런 것들을 하지 않길 추천합니다. 
이것은 재귀 트리의 좋은 직관입니다. 
여러분이 이것을 증명하는 방법은 무엇이죠? 대입 메소드 입니다. 
좋아요. 여러분이 해야 하는 것은 여러분의 추측을 위해 이것을 사용하고 
여러분의 추축이 맞다는 것을 증명하기 위해 대입을 사용하는 것입니다. 
이 메소드로 실수를 하기가 매우 쉽습니다. 
실수를 하기가 정말 쉬워요.
대입 메소드를 가지고 하면 실수를 하기가 어렵습니다  
왜냐하면 대수가 있기 때문입니다.
여러분이 적절하지 못하게  
그리거나 잘못 쓴 점 점 점들이나
트리 보다 입증하기가 더 쉽습니다.
알겠죠? 
그래서, 이것은 n log n 입니다. 매우 좋습니다. 
그것은 θ(nlog n) 입니다. 그리고 우리는 운이 좋습니다. 

English: 
Now let's try another one.
This is all for intuition
because, I will tell you,
by the time we get to the end
of this class you folks are
going to bolting for the door
because we are going to do some
good math today,
actually.
It is actually fun math,
I think, but it is challenging.
If you are not awake,
you can still sleep now,
but I will tell you when to
wake up.
One more bit of intuition.
Suppose that we alternate
steps.
Suppose we do the partitioning
thing.
And it happens that we start
out lucky and then we have a
partitioning step that is
unlucky and then we have a step
that is lucky and a step that is
unlucky and we do that all the
way down the tree.
Suppose we alternate.

Korean: 
이제 다른 하나를 시도해 봅시다. 이것은 직관을 위한 모든 것 입니다, 
왜냐하면 우리는 오늘 좋은 수학을 할 것인데,  
수업이 끝날 때까지
문을 닫아야 합니다. 
그것은 사실 재미있는 수학이지만, 좀 어렵습니다. 
만약 여러분이 깨어 있지 않으면, 
여러분은 여전이 자고 있을 수도 있겠네요 저는 여러분에게 언제 일어날지 알려드릴게요. 
하나 더 직관이 있습니다. 
우리가 단계들을 번갈아 한다고 가정해 보세요. 
우리가 분할을 한다고 가정해 보세요. 
우리는 운이 좋은 것에서 시작하지만 우리는 운이 나쁜 분할 단계를 가집니다 
그리고 우리는 운이 좋은 단계와 운이 좋지 않은 단계를 가지고 있고 
우리는 그것들을 모두 할 것입니다. 
우리가 번갈아 한다고 가정해 보세요. 

English: 
Are we lucky or unlucky if we
do that?
This time I want everybody
voting.
It doesn't matter what your
answer is.
Everybody has to have a stake
in the game.
It is sort of like horseracing.
If ever you have watched
horseracing, it is really
boring, but if you put a little
bit of money down,
a little skin in the game
suddenly it is interesting.
The same thing here.
I want everybody to put some
skin in the game.
Who thinks that this is going
to be lucky?
Who thinks it is going to be
unlucky?
OK.
Who didn't vote?
[LAUGHTER] You guys.
No skin in the game,
ha?
Let's analyze this so we can
once again write a recurrence.
On the lucky step,
we will have L(n) be the
running time on a lucky step of

Korean: 
우리가 그것을 한다면 우리는 운이 좋은걸까요? 나쁜걸까요? 
이번에 저는 여러분이 모두 투표를 했으면 좋겠네요. 
여러분이 답이 무엇이지는 중요하지 않습니다. 
모두 참여를 해야 해요. 
일종의 경마 같은 것이지요. 여러분이 경마를 본 적이 있다면, 
그것은 정말 지루합니다, 그러나 
여러분이 거기에 돈을 약간 걸었다면, 
갑자기 게임이 흥미로워집니다. 여기서도 마찬가지에요.
저는 여러분이 모두 참여하길 바랍니다. 
이것이 운이 좋다고 생각하는 학생 있나요? 
이것이 운이 나쁘다고 생각하는 학생 있나요? 
좋아요. 
누가 투표를 안 했죠? 
이것을 분석해봅시다 
그래서 우리는 다시 재귀를 쓸 수 있습니다. 운이 좋은 단계에서, 
L(n)은 사이즈 n의 운 좋은 스텝의 러닝 타임이 될 것입니다. 

Korean: 
그리고 그것은 두 번이 될 것입니다. 
반면에 다음 단계는 운이 나쁠 것입니다. 
여기 두 가지 운이 나쁜 것이 있습니다. 
그것은 우리의 운 좋은 단계입니다. 그리고 운이 나쁜 단계를 위해 
그것은 필수적으로 n-1의 L이 될 것입니다,
그것은 다음 단계에서 운이 좋을 것입니다, 더하기 θ(n). 
그것은 운이 나쁩니다.
경계 케이스에서 의존적인 재귀의 시스템으로 제가  
이 행동을 어떻게 그렸는지 보세요,
재귀는 정수 입력을 가지고 정수의 답을 가집니다. 
이제 우리는 대입을 사용하는
약간의 대수학을 할 것입니다. 

English: 
size n.
And that is going to be twice.
While the next step is going to
be unlucky.
It is two unluckies over 2 plus
order n.
That is our lucky step.
And then for the unlucky step
it is essentially going to be L
of n minus 1,
it is going to be lucky on the
next step, plus order n.
That is unlucky.
See how I have described this
behavior with a system now of
recurrences that are dependent
where the boundary cases,
once again which are unstated,
is that the recurrences have a
constant solution with constant
input.
Now we just do a little bit of
algebra using substitution.
L(n) is then equal to,

English: 
well, I can just plug in,
for U(n/2) plug in the value of
U(n/2).
And that gives me 2[L(n/2-1) +
Theta(n) + Theta(n)].
See what I did here?
I simply plugged in,
for U(n/2), this recurrence.
In fact, technically I guess I
should have said Theta(n/2) just
to make this substitution more
straightforward.
It is the same thing,
but just to not skip a step.
That we can now crank through.
And that is 2L(n/2 - 1) +,
and now I have two T(n/2) plus
another one, so all of that is

Korean: 
L(n)은 다음과 같습니다. 
그리고 그것은 저에게 2(L(n/2-1) + θ(n)) + θ(n) 를 줍니다. 
제가 여기서 무엇을 했는지 보겠어요? 
저는 단지 U(n/2)를 위해 이 재귀를 연결했습니다. 
사실, 기술적으로 저는 θ(n/2)이 이 재귀를 만든다고 
더 쉽게 말했어야 했습니다.
그것은 같은 것입니다, 그러나 단계를 생략하지 않습니다. 
우리가 지금 할 수 있는 것들입니다. 그리고 그것은 2L(n/2 - 1) +, 
그리고 이제 우리는 2 T(n/2) 더하기 다른 것을 가지고, 그것들은 모두 θ(n) 입니다. 

English: 
just order n.
And what is the solution to
that recurrence?
n log n.
Theta(n lg n).
Does everybody see that?
OK?
Theta(n lg n).
This is basically just,
once again, master theorem with
a little bit of jiggering here.
That minus one is only going to
help us, actually,
in the solution of the master
theorem.
So, it is order n lg n.
We are lucky.
If we alternate lucky and
unlucky, we are lucky.
How can we insure that we are
usually lucky?
If I have the input already

Korean: 
그리고 그 재귀의 답이 무엇이죠? 
n log n.
θ(nlg n). 모두 알겠나요?
네? θ(nlg n) 입니다. 
이것은 기본적으로, 다시 한번, 여기서 마스터 정리 입니다. 
그 마이너스 1은 우리를 도와줄 것입니다, 
사실, 마스터 정리의 답에서요. 
그래서 그것은 θ(nlg n) 입니다. 
우리는 운이 좋습니다. 우리가 운이 좋은 것과 나쁜 것을 번갈아 하면, 
우리는 운이 좋습니다. 우리가 보통 운이 좋다는 것을 어떻게 보장할 수 있죠? 
제가 이미 정렬된 입력을 가지면, 

Korean: 
저는 운이 나쁠 것입니다.
뭐라고요? 여러분은 인자들을 무작위로 배열할 수 있습니다, 
그것이 하나의 방법입니다. 또 다른 방법은 무엇이 있을까요? 
사실, 그것은 완벽하게 좋은 방법입니다. 
사실, 그것은 일반적인 것이에요. 
무작위로 중심점을 선택하세요. 좋아요. 
그것들은 효과적으로 같아야 하지만, 
우리는 무작위로 중심점을 선택할 것입니다. 
왜냐하면 그것이 분석하기 더 쉽습니다. 
그러나 그것들은 효과적으로 동등하지는 않습니다. 
그런 아이디어로부터 랜덤 퀵 정렬 알고리즘을 생각해볼 수 있습니다.
랜덤 퀵 정렬에 대해 좋은 것은 러닝 타임이 

English: 
sorted, I am going to be
unlucky.
Excuse me?
You could randomly arrange the
elements, that is one way.
What is another way?
That is a perfectly good way,
actually.
In fact, it is a common thing
to do.
Randomly choose the pivot,
OK.
It turns out those are
effectively equivalent,
but we are going to do the
randomly choose the pivot
because it is a little bit
easier to analyze.
But they are effectively
equivalent.
That gives us the algorithm
called randomized quicksort.
And the nice thing about
randomized quicksort is that the

Korean: 
입력 순서에 의존적이지 않다는 것입니다. 
제가 입력을 섞으면, 같은 이유로, 
그것은 입력 순서에 의존적이지 않습니다. 
만약 제가 무작위로 입력을 섞으면, 그것은 입력이 무엇이었는지는 중요하지 않습니다.
반면에, 원래의 퀵 정렬은 어떤 느린 케이스, 정렬된 또는 역으로 정렬된 입력, 
그리고 어떤 빠른 케이스들을 가지고 있습니다. 
특히, 그것이 .
무작위라면 그것은 매우 빠를 것입니다
만약 제가 무작위로 입력이나 중심점을 섞으면, 
그것은 입력이 무엇이었는지가 중요하지 않습니다. 
이것에 대해 생각하는 하나의 방법은 적수가 있습니다. 
여러분의 적을 상상해 보세요, 
여러분은 좋은 정렬 알고리즘을 가지고 있다고 말하고, 
적은 자신이 좋은 정렬 알고리즘을 가지고 있다고 말합니다. 여러분은 한 명의 고객에게 팔려고 
노력하고 있습니다. 그러면 고객은 
여러분들에게 기준을 제시하라고 말할 것입니다. 
그리고 여러분은 그의 알고리즘을 보게 될 것입니다.
자, 여러분은 보고 말합니다, 

English: 
running time is independent of
the input ordering.
Very much for the same reason
that if I just scramble the
input, it would be independent
of the input ordering.
If I randomly scramble the
input then it doesn't matter
what the order of the input was.
Whereas, original quicksort has
some slow cases,
input sorted or reverse sorted,
and some fast cases.
In particular,
it turns out that if it is
random it is going to be pretty
fast.
If I actually randomly scramble
the input or pivot on a random
element, it doesn't matter what
the input was.
One way of thinking about this
is with an adversary.
Imagine your adversary,
you are saying I have a good
sorting algorithm and he says I
have a good sorting algorithm
and you're trying to sell to a
single customer.
And the customer says OK,
you guys come up with
benchmarks for each of your
algorithms.
And you get to look at his
algorithm.
Well, you look and you say oh,

English: 
he is using quicksort.
I will just give him something
that is already sorted.
That is what you could do to
him.
If you had quicksort,
he would do the same thing to
you.
So, how can you defeat him?
Well, one way is with
randomization.
Big idea in computer science,
use random numbers.
The idea here is if I permute
the ordering at random,
as one suggestion,
or I pivot at random places,
then the input ordering didn't
matter.
And so there is no bad ordering
that he can provide that is
going to make my code run
slowly.
Now, I might get unlucky.
But that is just unlucky in my
use of my random-number
generator.
It is not unlucky with respect
to what the input was.
What the input was doesn't
matter.
Everybody follow that?
OK.
The nice thing about randomized
quicksort is that it makes no
assumptions about the input

Korean: 
그는 퀵 정렬을 사용하고 있군. 저는 그에게 이미 정렬된 것을 줄 것입니다. 
그것이 여러분이 그를 위해 할 수 있는 것입니다. 
여러분이 퀵 정렬을 가진다면, 
그는 여러분과 같은 것을 할 것입니다. 
그래서, 어떻게 그를 이길 수 있죠? 자, 하나의 방법은 랜덤화입니다. 
컴퓨터 과학에서 큰 생각인데, 
무작위의 수를 사용하는 것이지요. 
여기서 제가 하나의 제안으로써 순서를 바꾸면, 
또는 중심점을 무작위한 곳에 두면, 입력 순서는 중요하지 않습니다.
그리고 제 코드를 느리게 만드는 
그가 제공 할 수 있는 나쁜 순서가 없습니다. 
이제, 저는 운이 나쁠지도 모릅니다. 
그러나 제 랜덤 수 생성기의 사용에 있어서만 운이 나쁜 것입니다. 
입력이 무엇이었는지에 대해서는 운이 나쁘지 않습니다.
입력이 무엇이었는지는 중요하지 않습니다. 
모두 알겠나요? 
좋아요. 랜덤 퀵 정렬에 대해 좋은 것은 
그것이 입력 분배에 대한 추정을 하지 않는다는 것입니다.

Korean: 
여러분은 모든 입력들이 같다고 가정할 필요가 없습니다 
왜냐하면 여러분은 그것을 그 방법으로 할 수 있고 
중심점을 효과적인 방법으로 할 수도 있기 때문입니다. 
그리고 특히, 
worst-case에서의 동작을 이끌어 낼 수 있는 특정한 입력이 없습니다. 
worst-case는  

English: 
distribution.
You don't have to assume that
all inputs are equally likely
because either you can make it
that way or you pivot in a way
that makes that effectively
whole.
And, in particular,
there is no specific input that
can elicit the worst-case
behavior.
The worst-case is determined

Korean: 
오직 랜덤 수 생성기에 의해 결정됩니다.
그러므로, 그것이 오직 랜덤 수 생성기에 의해서만 결정되기 때문에, 
우리는 필수적으로 수학적으로 운이 나쁜 것을 해야 합니다. 
이상한 점이 무엇이죠? 
우리는 이것을 분석할 것입니다. 
그리고 이것은 여러분이 이 수업을 듣든 안 듣든 알아야 하는 것입니다. 
여러분이 6.042 수업을 건너 뛰든 뭐든지 간에, 
이것은 비교를 하는 좋은 곳입니다.
잠시 일어서서 
스트레칭을 하는게 어떤가요? 
이것이 우리가 할 좋은 수학이기 때문에, 
여러분은 그것을 위해 상쾌함을 느끼길 원할 겁니다. 

English: 
only by a random-number
generator.
And, therefore,
since it is only determined by
a random-number generator,
we can essentially bound the
unluckiness mathematically.
We can say what are the odds?
So, we are going to analyze
this.
And this is where you know if
you belong in this course or
not.
If you have skipped 6.042 or
whatever, this is a good place
to do the comparison.
Since it is going to be a
little bit, why don't people
just stand up for a moment and
take a stretch break.
Since this is going to be a
nice piece of mathematics we are
going to do, you are going to
want to feel fresh for it.

Korean: 
스트레칭 시간은 끝났습니다. 
분석해보죠. 좋아요. 
저는 우리가 이것을 만들 수 있다고 생각합니다.
저는 일종의 레이스를 할 것입니다. 
오늘 해야 할 많은 것들이 있습니다. 좋아요. 
T(n)을 이제 무작위의 변수라고 합니다.
와우. 저는 우리가 여기서 했던 것을 여기 쓰지도 않았네요. 
그래서, 우리는 중심점을 랜덤 인자로 둘 것입니다. 

English: 
Stretch break is over.
Analysis.
Good.
I think we are going to make
this.
I am sort of racing.
There is a lot of stuff to
cover today.
Good.
Let's let T(n) now be the
random variable for the running
time assuming --
Wow.
I didn't even write here what
we did here.
So, we are going to pivot on a
random element.

English: 
That is the basic scheme we are
going to do.
And the way I do that,
by the way, is just in the code
for partition,
rather than partitioning on the
first element,
before I do the partition,
I just swap the first element
with some other element in the
array chosen at random,
perhaps itself.
So, they are all equally likely
to be pivoted on.
And then just run the ordinary
partition.
This is a random variable for
running in time assuming,
we have to make an assumption
for doing probability,
the random numbers are
independent.
So that when I pivot in one
place, it is independent of how
I pivoted in some other place as
I am running this algorithm.
Then, to analyze this,
what I am going to do is I want
to know where we pivoted.
For k = 0, 1,

Korean: 
그것이 우리가 하려고 하는 기본적인 골격입니다. 
그리고 제가 하는 방법은 분할을 위한 코드에 있습니다, 
첫 번째 인자의 분할이라기 보다는요 
저는 분할 하기 전에, 
첫 번째 인자를 배열에서 무작위로 골라진 
어떤 다른 인자와 바꿉니다. 
그래서, 그것들은 모두 동등하게 중심점이 될 수 있습니다. 
그리고 평범한 분할을 합니다.
이것은 랜덤 변수입니다, 
우리는 가능성을 위해 가정을 해야 합니다, 
랜덤 수들은 독립적입니다. 
그래서 우리가 중심점을 한 곳에 둘 때, 
그것은 제가 이 알고리즘을 돌릴 때 어떤 다른 곳에 중심점을 두었는지에 독립적입니다.
이를 분석하기 위해, 제가 하려는 것은 저는 중심점이 어디에 있는지 알고 싶습니다.
k = 0, 1, ..., n-1 에 대해서요. 

Korean: 
특별한 분할을 위해서, 
랜덤 변수 X_k = 1 라고 둡시다.
분할이 k : n-k-1 를 생성한다면요.
분할 루틴에서, 저는 랜덤 인자를 중심점으로 고를 것입니다. 
그리고 X_k는 랜덤 인자 입니다. 
그것이 중심점 왼쪽에 k개 인자 오른쪽에 
n-k-1 인자를 생성한다면 그 인자는 1입니다.
물론, 그것들 중 어떤 것은 n-1 입니다 

English: 
..., n-1, let's let,
for a particular partition,
the random variable X_k = 1 if
partition generates a k :
n-k-1 split,
and 0 otherwise.
In the partition routine,
I am picking a random element
to pivot on.
And X_k is going to be my
random variable that is 1 if it
generates a split that has k
elements on the left side and
n-k-1 elements on the right side
of the pivot.
Some of those,

English: 
too, of course are n-1 because
I also have the pivot.
And 0 otherwise.
So, I now have n random
variables that I have defined
associated with a single
partition where all of them are
going to be zero except one of
them, whichever one happens to
occur is going to have the value
1.
This is called,
by the way.
What is the name of this type
of random variable?
Bernoulli.
Well, Bernoulli has other
assumptions.
It is an indicator random
variable.
It turns out it is Bernoulli,
but that's OK.
It is an indicator random
variable.
It just takes on the value of
0, 1.
And Bernoulli random variables

Korean: 
왜냐하면 저는 또한 중심점을 가지거든요. 
그렇지 않으면 0 입니다. 
저는 이제 그것들 중 하나를 제외하고 모두 0이 되는 
하나의 분할과 관련하여 정의하는 
n 랜덤 변수들을 가집니다. 
그런데 이것을 뭐라고 하죠? 
이 랜덤 변수 타입의 이름이 무엇이죠?
Bernoulli 입니다. 자, Bernoulli는 다른 가정들을 가집니다. 
그것은 지시자 랜덤 변수 입니다. 
그것은 Bernoulli이지만, 괜찮습니다. 
그것은 지시자 랜덤 변수 입니다. 
그것은 변수 0, 1을 가집니다. 
그리고 Bernoulli 랜덤 변수들은  

Korean: 
지시자 랜덤 변수의 특정한 타입입니다.
이것들이 그렇다는 것으로 알려졌습니다. 그것은 지시자 랜덤 변수 입니다. 
지시자 랜덤 변수들은 여러분이 
그것들의 합을 계산하려고 노력할 때 좋은 방법입니다.
여러분의 큰 랜덤 변수들을 분석 될 수 있는 
작은 것들로 나누는 좋은 방법입니다. 
이 지시자 랜덤 변수를 봅시다. 
X_k는 무엇과 같을 것으로 기대됩니까?
다시 말해, 제가 k : n-k-1 을 생성할 
확률은 무엇입니까? 

English: 
are a particular type of
indicator random variable.
Which it turns out these are.
That is an indicator random
variable.
Indicator random variables are
a good way when you are trying
to understand what the sum of a
bunch of things is.
It is a good way to break apart
your big random variables into
smaller ones that can be
analyzed.
Let's just take a look at this
indicator random variable.
What is the expectation of X_k
equal to?
In other words,
what is the probability that I
generate a k :
n-k-1 split?

English: 
X_k is, let's just write out
what that means,
just to refresh people's
memory.
That is 0 times the probability
that X_k equals 0 plus 1 times
the probability that X_k equals
1, which is equal,
well, that is all zero.
That is just equal to the
probability that X_k equals 1.
And that is a general property
of indicator random variables,
is that their expectation is
the probability that they are 1.
The nice thing about indicator
random variables is it directly
connects the probability to the
expectation without any other
terms going on.
What is the probability of X_k
equals 1?

Korean: 
X_k가 의미하는 것을 써봅시다, 
여러분의 기억을 되살리기 위해서요. 
X_k가 0이면 확률은 0입니다, 
X_k가 1이면 확률은 1입니다. 
X_k가 1이면 같습니다. 
그리고 그것은 지시자 랜덤 변수들의 일반적인 속성입니다, 
그것들의 기대값은 그것들이 1인 확률입니다. 
지시자 랜덤 변수들에 대해 좋은 것은 그것이 
다른 것들 없이 기대값의 확률과  
직접적으로 연결된다는 것입니다.
X_k가 1인 것의 확률이 무엇이죠? 

English: 
1/n.
So, all splits are equally
likely.
And I have n elements,
so each ones has a 1/n chance
of being picked as the pivot.
And, once you pick the pivot,
that determines what is on the
left and the right and so forth.
So, it is 1/n.
Everybody with me so far?
More or less?
OK.
As I say, this is going to test
whether you're in the class.
If you go home and you study
this and you cannot get it,
and you have a deficiency in
your math background in trying
to take the course,
this is a good indication that
probably you have taken
something a little over your
head.
Let's write out what T(n) is
equal to here.

Korean: 
1/n 입니다. 그래서 모든 것은 같을 것입니다. 
그리고 저는 n 개의 인자들을 가지고 있습니다, 
각각은 중심점으로 선택될 1/n의 확률을 가지고 있습니다. 
그리고, 여러분이 한번 중심점을 고르면, 그것은 왼쪽이 무엇인지 오른쪽이 무엇인지를 결정합니다. 
그래서, 그것은 1/n 입니다. 
모두 지금까지 이해했나요? 좋아요.
제가 말한 바대로, 이것은 여러분이 이 수업에 있든 없든 테스트가 될 것입니다. 
여러분이 집에 가서 이것을 공부하는데 모르겠으면, 
그리고 여러분이 수업을 이해하는데 수학적 
배경지식이 부족하면, 
이것은 여러분의 머리 속에 조금 집어 넣을 수 있는 
좋은 암시입니다. 
여기서 T(n) 이 무엇과 같은지 써봅시다.

English: 
T(n) is going to be equal to
T(0) + T(n-1) + Theta(n) if we
get a 0 : n-1 split and is equal
to T(1) + T(n-2) + order n if we
have a 1 : n-2 split.
And now down here it is going
to be T(n-1) + T(0) + Theta(n)
if we end up with an n-1 :
0 split.

Korean: 
T(n) 은 T(0) + T(n-1) + θ(n)과 같을 것입니다. 
우리가 1 : n-2을 가지고 있을 때 우리가 0 : n-1을 얻고 T(1) + T(n-2) + θ(n)과  
같다면요.
그리고 이제 여기서 그것은 be T(n-1) + T(0) + θ(n)이 될 것입니다  
우리가 n-1 : 0으로 끝나면요.

English: 
So, this is our recurrence for
T(n).
And, unfortunately,
the recurrence is kind of hairy
because it has got n cases.
And this is,
once again, where the
brilliance of being able to use
indicator random variables comes
in.
Because we will be able to take
this case analysis and reduce it
to mathematics so we don't have
cases using indicator random
variables.
And the way we do that is using
the following trick of
converting the cases into a
summation.

Korean: 
그래서, 이것은 T(n)을 위한 우리의 재귀입니다. 
그리고, 불행히도, 재귀는 스릴 있습니다 
왜냐하면 그것은 n 개의 케이스를 가지고 있습니다. 그리고 이것은, 
다시 한번, 지시자 랜덤 변수들을 
사용할 수 있는 것입니다. 
우리가 이 경우를 분석 할 수 있고 그것을 수학으로 줄일 수 있기 때문에 
우리는 지시자 랜덤 변수들을 사용하는 케이스들을 가지지 않습니다.
그리고 우리가 그것을 하는 방법은 케이스들을 
합으로 변환하는 방법을 
사용하는 것입니다. 

English: 
Let's just take a look at why
these two things are the same.
The indicator random variable
is zero, except if you get the
particular split.
Therefore, this summation is
going to be zero,
except for that k which
actually appeared in which case
it is the value that we say it
is.
See the trick using
multiplication by 0,
1 variable to handle all the
cases?
I think that is damn clever.
I think that is damn clever.
And this is like the classic
thing that you do with indicator
random variables.
It's one of the reasons they
are a very powerful method.
Because now we actually have a
mathematical expression,
hairy although it may be,
for our recurrence.
Now, what we are going to
analyze is the expected value of

Korean: 
이 두 개가 왜 같은지 봅시다.
지시자 랜덤 변수는 0 입니다, 여러분이 특정한 것을 가지는 경우를 제외하고요. 
그러므로, 이 합은 0 이 될 것입니다,
k가 특정한 값을 가지는 경우를 제외하고요. 
모든 케이스들을 다루기 위해 0, 1 
변수에 의한 곱셈을 
사용하는 것을 봅시다.
저는 그것이 현명하다고 생각합니다. 
저는 그것이 현명하다고 생각해요.
그리고 이것은 여러분이 지시자 랜덤 변수들을 다루는 고전적인 것 입니다. 
그것은 그것들이 매우 강력한 메소드인 이유 중 하나입니다. 
이제 우리가 사실 수학 식을 가지고 있기 때문에, 
그것이 그렇다 할지라도, 우리의 재귀를 위해서요. 
이제, 우리가 분석해야 하는 것은 T(n)의 기대값 입니다. 

English: 
T(n).
That is what we want to do.
What is the expected value of
T(n)?
To do that, I just write the
expected value of T(n) is equal
to the expected value of this
big summation.
And now we can go ahead and
start to evaluate the expected
value of that summation.
Everybody with me?
Yes?
Any questions at this point?
I see a thumbs up.
That's nice to see.
But I generally believe that
what I want to see is no thumbs
down.
It is good to see the thumbs
up, but that means one person
understands, or thinks he
understands.
[LAUGHTER] So,
this is, I claim,
equal to the following.
Actually, I am going to need a
little space here so I am going

Korean: 
그것은 우리가 원하는 것입니다. 
T(n)의 값은 무엇으로 기대되나요? 
그것을 하기 위해, 저는 T(n)의 기대되는 값이 큰 합의 
기대되는 값과 같다고 쓸 것입니다. 
그리고 이제 우리는 나아갈 수 있고 그 합의 기대값을 
구할 수 있습니다. 모두 알겠나요?
네? 여기서 질문 있나요? 
저는 엄지손가락이 올라간 것을 보았습니다. 좋아요. 
그러나 일반적으로 제가 원하는 것은 엄지손가락이 내려가는 것을 보지 않는 것입니다. 
엄지가 올라간 것을 보니 좋지만, 
그것은 한 학생이 이해한다는 것을 의미하네요.  
그래서,
이것은, 다음과 같습니다. 
사실, 저는 여기서 작은 공간이 필요합니다 

English: 
to move the equal sign over a
little bit.
I claim that summation is equal
to that.
This expectation is equal to
that summation of expectations.
Why is that?
What are the magic words that
justify this step?
Linearity of expectation.
The expectation of a sum is the
sum of the expectations.
So, that is linearity of
expectation.
I don't need independence for
that.
That is just always true for
expectation of any random

Korean: 
등호를 조금 옮길게요.
저는 저 식이 아래의 것과 같다고 생각합니다. 
이 식은 기대값들의 합입니다. 
왜죠? 이 단계를 정당화하는 마법의 단어들은 무엇입니까? 
기대값의 선형성입니다. 
합의 기대값은 기대값의 합입니다. 
그래서, 그것은 기대값의 선형입니다. 
저는 그것을 위한 독립성이 필요하지 않습니다. 
그것은 어떤 랜덤 변수들을 위해서도 항상 옳습니다. 

English: 
variables.
The sum of the expectations is
the expectation of the sum and
vice versa.
Here we did the vice versa.
That is equal to now the sum of
k=0 to n-1 of expectation of X_k
[T(k) + T(n-k-1) + Theta(n)].
Why is that true?
What I have done is I've said
the expectation of the product
is the product of the
expectations.
That is because of

Korean: 
기대값들의 합은 합의 기대값이고 
역도 성립합니다. 
여기서 우리는 역도 성립한다는 것을 했습니다. 
그것은 이제 X_k [T(k) + T(n-k-1) + θ(n)]의 기대값의 k=0 에서 n-1까지의 합과 같습니다.
왜 이것이 옳은가요? 제가 한 것은 산물의 기대값이 
기대값들의 산물이라는 것입니다. 
이것은 독립성 때문입니다. 

Korean: 
무엇의 독립성이죠? 
여기서 X_k, 랜덤 변수는 어떤 다른 분할의 것과 
독립적입니다, 
X_k는 다른 재귀 호출을 위해 
존재합니다. 
그래서, 여기서 무엇이 일어나는지는 저기서 무엇이 일어나는지와 독립적입니다. 
우리는 사실 숨기고 있습니다. 
우리가 재귀를 가지기 때문에, 우리는 매 번 같은 시간으로 분할하지 않습니다. 
우리는 다른 것을 가집니다.
우리는 사실 여러분이 관심을 기울여야 하는 수학 아래에서 
T(k)에서 만들어지고 있는 
랜덤 선택들의 집합이 있다는 것, 
즉 수학이 혼자 보여주지 않는 것을 할 것입니다. 
그리고 여러분은 그것들이 그것들과 
독립적이라는 것을 이해해야 합니다. 
우리는 기대값들의 확률을 곱할 수 있습니다. 
모두 알겠나요? 그것은 큰 것입니다. 

English: 
independence.
What is independent of what?
The X_k here,
random variable,
are independent of any of the
other partitionings in,
if you will,
the X_k that would exist for
any of the other recursive
calls.
So, whatever happens in here is
independent of what happened
there.
We are actually hiding.
Since we have a recurrence,
we are not partitioning the
same wage time.
We have a different one.
We actually have something
going on underneath the
mathematics you have to pay
attention to that the
mathematics alone isn't really
showing, which is that in T(k)
there is actually a set of
random choices that are being
made, if you will.
And so you have to understand
that those are independent of
those, in which case we can
multiple the probabilities of
their expectations.
Is everybody with me?
That is a big one,

Korean: 
다른 랜덤 선택들로부터 X_k와 독립적입니다.
무엇보다도, 그것은 이제 같습니다, 
좋아요. X_k의 기대값은 무엇입니까? 
1/n. 그것은 사실 합에 속하지 않습니다. 
우리는 그것을 밖에서 할 것입니다. 
저는 1/n 곱하기 T(k)의 기대값의 k=0 부터 n-1까지의 합 + T(n-k-1) 의 , 
기대값의 k=0 부터 n-1까지의 합

English: 
independence of X_k from other
random choices.
That is equal to now,
well, first of all,
this is nice.
What is the expectation of X_k?
1/n.
That actually doesn't even
belong in the summation.
We will just pop it outside.
I get 1/n times the sum of k=0
to n-1 of expectation of T(k) +
1/n summation k=0 to n-1 of
expectation of T(n-k-1) + 1/n

English: 
summation k=0 to n-1 up to
Theta(n).
That is, again,
using linearity of expectation
there this time to split up
these pieces and just factoring
out the expectation of k as
being 1/n.
Everybody with me still?
All of this is elementary.
It is just one of these things
that is hard just because there
are so many steps.
And it takes that you have seen
some of this before.
Now the next observation is
that these two summations are,
in fact, identical.
They are the same summation,
just in a different order.
This is going T(0),
T(1), T(2), T(3) up to T(n-1).

Korean: 
θ(n)까지 입니다. 
즉, 다시, 기대값의 선형성을 이용하여 이것들을 쪼개고 
k의 기대값을 1/n 로써
제외하는 시간이 있습니다.
따라오고 있죠? 이 모든 것은 기초적인 것입니다. 
이것들은 어려운 것들 중 하나입니다 왜냐하면 많은 단계들이 있거든요.
그리고 그것은 전에 여러분이 이것들 중 어떤 것을 보았던 것입니다. 
이제 다음에 볼 것은 이 두 개의 합이 
사실 동일하다는 것입니다.
그것들은 동일한 합입니다, 다른 순서에서요. 
이것은 T(0), T(1), T(2), T(3)에서 T(n-1) 까지 입니다. 

English: 
This one is going T(n-1),
T(n-2), T(n-3) down to T(0).
These are, in fact,
equal.
So, therefore,
I have two of them.
And then what is this term
equal to?
What is that one equal to?
Theta(n).
Let's just see why.
The summation of 0 :
n of Theta(n) is Theta(n^2)
divided by n.
Or, if I want to bring the
Theta(n) out,

Korean: 
이것은 T(n-1), T(n-2), T(n-3)에서 T(0) 까지 입니다. 
사실, 이것들은 같습니다. 
그러므로, 저는 그것들 중 두 개를 가집니다. 
그리고 이 항은 무엇과 같죠?
그것은 무엇과 같죠? θ(n)입니다. 
왜 그런지 봅시다. θ(n)의 0 : n의 합은 
θ(n^2) 나누기 n 입니다. 
여러분이 θ(n)을 꺼내고 싶다면, 

Korean: 
저는 1 곱하기 θ(1)의 k=1부터 n까지의 합을 가집니다.
다시 한번,  
여러분은 n을 얻습니다.
즉, 어떤 면에서, 합이 동일한 항을 가지기 때문에, 
이것은 단지 대수입니다. 
이제 우리가 하려고 하는 것은 기술적인 편리함을 위해 무엇을 하는 것입니다.
우리는 k=0, 1 항들을 기술적인 편의를 위해 
θ(n)으로 흡수하려고 합니다. 
우리는 여기서 θ(n) 을 가지는 재귀를 가집니다. 
그리고, 제가 k=0 또는 1인 케이스를 보면, 
저는 기대값이 무엇인지 압니다. 0, 1을 위해, 예상 비용은 정수인 

English: 
I have 1 times the summation of
k equals1 to n of Theta(1) or of
1.
So, once again,
you get n, either way of doing
it.
This is, in some sense,
because the summations have
identical terms,
and this is just algebra.
Now what we are going to do is
do something for technical
convenience.
Because we are going to absorb
the k=0, 1 terms into the
Theta(n) for technical
convenience.
We have a recurrence here where
I have an order n.
And, if I look at the cases
where k=0 or k=1,
I know what the expectation is.
For 0, 1, the expected cost is

Korean: 
worst-case의 비용입니다. 
저는 상수 사이즈의 문제만을 풀기 때문입니다. 
그리고 우리는 어떤 경계 경우를 위해서도 우리의 재귀의 답은 
그것이 상수 시간이라는 것을 압니다. 
그래서, 저는 기본적으로 이 항들을 꺼낼 것입니다. 
그리고 그것을 하는 모든 것은 여기 Theta(n) 에서 
상수를 더 많이 축적하는 것입니다. 
그것은 재귀의 답을 더 쉽게 만드는 답입니다.
그리고 제가 그것을 하면, 
저는 T(n) = 2/n T(k) + θ(n)의 기대값의 k=2 부터 n-1까지의 
합의 기대값을 얻습니다.

English: 
the worst case cost,
which is constant.
Because I am only solving the
problem for a constant size.
And we know that for any of the
boundary cases that our solution
of recurrence,
our assumption is that it is
constant time.
So, I basically can just take
those two terms out.
And all that does it accumulate
some more constant here in the
Theta(n).
It is going to make the
solution of the recurrence a
little bit easier.
And, if I do that,
I get expectation of T(n) = 2/n
summation k=2 to n-1 of
expectation of T(k) + Theta(n).

Korean: 
그래서, 이 모든 것은 재귀를 도출하는 것입니다. 
그리고 이제 우리는 그것을 풀어야 합니다. 우리가 한 것을 보기 위해, 
우리는 case 문과 관련된 랜덤 변수를 위한 
재귀를 가지고 시작했습니다. 
우리는 그것을 case 문 없이 수학적인 것으로 변환했습니다, 
단지 생산물을 가지고요, 그리고 우리는 기대값을 위한 재귀를 도출했습니다. 
그리고 이제 우리는 그 재귀를 풀려고 하는 
과정에 있습니다. 
우리는 재귀의 단순화를 했습니다. 
그래서 우리는 우리가 여기서 풀려고 하는 것이 무엇인지 이해합니다. 
그런데, 저는 이것들을 퀴즈에 내지 않은 것 같네요. 

English: 
So, all of that work was to
derive the recurrence.
And now we have to solve it.
Just to review what we did,
we started out with a
recurrence which was for the
random variable which involved a
case statement.
We converted that into some
mathematics without the case
statement, just with a product,
and then we derived a
recurrence for the expectation.
And now we are in the process
of trying to solve that
recurrence.
We have done some
simplification of the recurrence
so that we understand what it is
that we are going to solve here.
By the way, I don't give things
like this on quizzes.

English: 
I do expect you to understand
it.
The elements of this you will
find on a quiz.
This is a lot of work to figure
out.
This took smart people to do.
Even though it is all
elementary, but working out
something like this at the
elementary level is still a bit
of work even for somebody who is
knowledgeable in this area.
Now we are going to solve that
last recurrence over there and
we are going to prove that the
expectation of T(n) is less than
or equal to (an lg n) for some
constant a greater than 0.
That is going to be what we are
going to do.
And so what technique do you
think we should use to prove
this?
Does this look like a master
method?

Korean: 
저는 여러분이 그것을 이해할 것이라 기대합니다.
이것의 인자들은 여러분이 퀴즈에서 보게 될 것입니다. 
이것을 알아 내기 위한 많은 일들입니다. 
이것은 똑똑한 사람들이 합니다. 그것이 모든 기초적인 것이라 할지라도, 
기초적인 수준에서 이와 같은 것을 하는 것은 이 분야에서 지식을 가진 누군가를 위해서는 
여전히 약간의 일입니다. 
이제 우리는 저기서 지난 재귀를 풀려고 하고 0 보다 큰 어떤 정수에 대하여 
T(n)이 (an lg n) 보다 
작거나 같은지의 기대값을 증명할 것입니다. 
그것은 우리가 하려는 것입니다. 
그리고 우리가 이것을 증명하기 위해 무슨 기술을 
사용해야 한다고 생각합니까? 
이것은 마스터 메소드 같아 보이나요?

English: 
It is nothing like the master
method.
So, when in doubt do
substitution.
It is the grand-daddy of all
methods.
What we will do is solve the
base case by simply choosing a
big enough so that (an lg n) is
bigger than the expectation of
T(n) for sufficiently large
small n.
So, I just pick a to be big
enough.
And this is,
by the way, why I wanted to
exclude 0 and 1 from the
recurrence.

Korean: 
이것은 마스터 메소드와 같은 것이 아닙니다. 
그래서, 대입을 합니다. 
그것은 모든 메소드의 할아버지입니다.
우리가 할 것은 충분히 큰 것을 선택하여 
기본적인 케이스를 푸는 것입니다. 
(an lg n) 는 충분히 큰 n에 대하여 T(n) 의 기대값 보다 큽니다.
그래서, 저는 충분히 큰 것을 고릅니다. 
그런데, 이것은 제가 재귀로부터 0과 1을 제외하길 
원했던 이유입니다. 

English: 
Because, for example,
when n=0, log of 0 is,
it's like dividing by 0,
right, you cannot do it.
Log of 1 is 0.
So here, even if I restricted
it to 1, here I would have a 0,
and I can't ever pick a big
enough to dominate those cases.
What I do is I just say look,
I just absorb whatever the cost
is into the T(n) for technical
convenience.
And that lets me address it as
(an lg n) to be big enough to
handle the base case.
So, that is why we made that
technical assumption.
We are going to use a fact
which is that the summation of

Korean: 
왜냐하면, 예를 들어, n=0 일 때, 
0의 로그는, 0으로 나누는 것 같지만, 여러분은 그것을 할 수 없습니다. 
1의 로그는 0 입니다. 그래서 여기서, 제가 그것을 1로 제한하더라도, 
여기서 저는 0을 가집니다, 그리고 저는 이 보든 경우를 지배하는 
충분히 큰 것을 고를 수 없습니다. 제가 하는 것은, 
비용이 무엇이든 기술적인 편의 위하여 흡수하는 것 입니다.
그리고 그것은 기본 케이스를 다루기 위해 그것을 
충분히 큰 (an lg n)로써 말하도록 합니다. 
그래서 그것은 우리가 기술적인 가정을 했던 이유입니다. 
우리는 k lg k의 k=2에서 n-1까지의 합이 1/2n^2 lg n - 1/8n^2 보다 

Korean: 
작거나 같다는 사실을 이용할 것입니다. 
저는 그것을 여러분의 숙제로 남겨둘 것입니다. 
저는 그것이 책에 연습문제에 있다고 생각해요. 
저는 여러분이 가서 이것을 평가해 보길 바랍니다. 
그것을 평가하는 두 가지 방법이 있습니다. 
하나는 순수하게 합을 사용하는 것과 
이 바운드를 증명하기 위해 합을 두 부분으로 나누고 그것을 재편성함으로써 
합에 대한 사실을 이용하는 것입니다.
다른 방법은 합을 풀기 위해  
적분 메소드를 사용하는 것입니다.
양쪽 방법으로 여러분은 풀 수 있습니다. 사실 적분 방법은
여러분이 이것 보다 더 타이트한 것을 얻게 해줍니다. 
이것은 기본적인 사실입니다, 그리고 여러분은 가야합니다 
그리고 그것을 하는 방법을 알아야 합니다. 대입을 해 봅시다. 

English: 
k=2 to n-1 of k lg k is less
than or equal to 1/2n^2 lg n -
1/8n^2.
I am going to leave that as an
exercise for you to workout.
I think it is an exercise in
the book, too.
I want you to go and evaluate
this.
There are two ways to evaluate
it.
One is by using purely
summations and facts about
summations by splitting the
summation into two pieces and
reconstituting it to prove this
bound.
The other way is to use the
integral method for solving
summations.
Either way you can prove.
The integral method actually
gets you a tighter bound than
this.
This is a basic fact,
and you should go off and know
how to do that.
Now let's do substitution.

English: 
The expectation of T(n) is less
than or equal to 2/n times the
summation k=2 to n-1,
now we do the substitution of
ak lg k, the smaller values plus
Theta(n).
I might mentioned,
by the way, that the hard part
of doing this,
it is easy to get the bound
without this term,
it is easy to get this bound,
1/2n^2 lg n,
it is harder to get the second
order term.
It turns out you need the
second order term in order to do
what we are going to do.

Korean: 
T(n)의 기대값은 2/n 곱하기 k=2에서 n-1까지의 합보다  
작거나 같습니다,
이제 우리는 θ(n) 더하기 ak lg k의 대입을 할 수 있습니다.
그런데, 저는 이것을 하는 어려운 부분을 언급했습니다. 
이 항 없이 바운드를 얻기 쉽습니다. 
이 바운드 1/2n^2 lg n를 얻기 쉽습니다, 
두 번째 오더 항을 얻기는 더 어렵습니다. 
여러분은 여러분이 하려는 것을 하기 위해 
두 번째 항이 필요합니다. 

English: 
You have to be able to subtract
a quadratic amount of the n^2 lg
n in order to make this proof
work.
And that is the trickier part
in evaluating that summation.
So, we get this.
That is less than or equal to?
Well, I happen to know how much
this is by using that formula.
I use my fact and get 2a/n
(1/2n^2 lg n - 1/8n^2) +
Theta(n).
Did I do something wrong?
There we go.
Very good.

Korean: 
여러분은 이 증명을 하기 위해 n^2 lg n의 
이차를 뺄 수 있어야 합니다. 
그리고 그것은 그 합을 평가하는데 있어서 까다로운 부분입니다. 
그래서, 우리는 이것을 얻습니다. 그것은 작거나 같습니까? 
자, 저는 그 공식을 사용함으로써 이것이 얼만큼인지 압니다. 
저는 제 사실을 이용하고 2a/n (1/2n^2 lg n - 1/8n^2) + θ(n)을 얻습니다.
제가 틀렸나요? 
계속 합시다. 좋아요. 그것은 다음과 같습니다. 

English: 
That is equal to -
If I multiply this first part
through that is an lg n.
And now, so I don't make a
mistake, I want to express this
as my desired,
this is what I want it to be,
minus a residual.
I am going to write the
residual as this part.
And so, the way to write that
is, that is going to be minus.
And then it is going to be this
term here, which is going to be

Korean: 
제가 이 첫 번째 부분을 곱하면 그것은 an lg n 입니다. 
그리고 이제, 저는 실수를 하지 않을 겁니다, 
저는 이것을 제가 원하는 것으로써 표현할 것입니다, 
이것은 제가 바라는 것, 마이너스 오차 입니다. 
저는 오차를 이 부분으로 쓸 것입니다. 
그리고, 그것을 쓰는 방법은, 그것은 마이너스 여야 합니다. 
그리고 나서 그것은 여기서 이 용어가 항이 될 것입니다, .

Korean: 
그 항은 an/4 - Theta(n) 입니다
그리고 그것은 이것이 양이면 an lg n 보다 작거나 같을 것입니다. 
그리고 저는 여기 θ(n)에서 상수를 지배하는 것과 같은 충분히 큰 것을 고름으로써 
그 부분을 양으로 할 수 있습니다. 
여기서 상수가 무엇이든, 
저는 충분히 큰 a를 찾을 수 있습니다 
그래서 이 항은 이 부분을 양으로 만듭니다. A가 충분히 크면 

English: 
an/4 - Theta(n).
And that is going to be less
than or equal to an lg n if this
part is positive.
And I can make that part
positive by picking a big enough
such that an/4 dominates the
constant in the Theta(n) here.
Whatever the constant is here,
I can find an a that is big
enough so that this term makes
this part positive.
If a is big enough so that an/4

English: 
dominates Theta(n).
And so the running time of
randomized quicksort is order n
lg n.
That is what we just proved,
the expected running time is
order n lg n.
Now, in practice,
quicksort is a great algorithm.
It is typically three or more
times faster than mergesort.
It doesn't give you the strong
guarantee necessarily of
mergesort and being worst-case n
lg n.
But in practice,
if you use randomized
quicksort, it is generally as
much as three times faster.
It does require code tuning in
order to get it up to be that
fast.
You do have to go and coarsen
the base cases and do some other
tricks there,
but most good sorting
algorithms that you will find
are based on quicksort.
Also one of the other reasons
it works well is because it

Korean: 
an/4는 θ(n) 지배합니다. 그리고 랜덤 퀵 정렬의 러닝 타임은 
θ(nlg n)입니다. 
그것은 우리가 증명했던 것입니다, 기대했던 러닝 타임은
θ(nlg n)입니다. 이제, 실제로, 
퀵 정렬은 훌륭한 알고리즘입니다. 그것은 전형적으로 합병 정렬 보다 3배 혹은 그 이상 빠릅니다. 
그것은 여러분에게 필수적으로 합병 정렬과 worst-case에서 n lg n 이 
되는 것의 강한 보장을 주지 않습니다.
그러나 실제로, 
여러분이 랜덤 퀵 정렬을 사용하면, 
그것은 일반적으로 3배 빠릅니다. 그것은 그것을 빠르게 하기 위해 
코드 수정을 필요로 합니다. 
여러분은 가서 기본적인 경우를 고치고 저기에 다른 방법으로 해보아야 합니다 
그러나 여러분이 찾을 수 있는 가장 좋은 정렬 알고리즘은  
퀵 정렬을 기반으로 합니다.
또한 그것이 효과적인 다른 이유들 중 하나는 그것이 가상 메모리에서 

Korean: 
캐쉬와 잘 작동하기 때문입니다.
우리는 알고리즘에서 요즘 큰 이슈들, 캐쉬 모델 등과 같은 것에 대하여  
많이 이야기 하지 않을 것입니다.
그러나 그것은 가상 메모리에서 캐쉬와 매우 잘 작동합니다. 
그것은 이것이 사용하기 좋은 알고리즘인 또 다른 이유입니다. 
그런데, 금요일에 수업이 있습니다. 
우리는 또 다른 n log n 알고리즘에 대해 배울 것이에요, 
금요일 수업은 정말 중요합니다.

English: 
tends to work well with caches
in virtual memory.
We are not really talking much
about caching models and so
forth, big topic these days in
algorithms, but it does work
very well with caches in virtual
memory.
It is another reason that this
is a good algorithm to use.
Good recitation,
by the way, on Friday.
We are going to see another n
log n time algorithm,
a very important one in
recitation on Friday.
