1 00:00:00,000 --> 00:00:00,500 2 00:00:00,500 --> 00:00:01,900 [MUSIC CHƠI] 3 00:00:01,900 --> 00:00:05,710 4 00:00:05,710 --> 00:00:09,150 >> DOUG LLOYD: Bởi bây giờ bạn biết rất nhiều về mảng, 5 00:00:09,150 --> 00:00:11,610 và bạn biết rất nhiều về danh sách liên kết. 6 00:00:11,610 --> 00:00:13,650 Và chúng tôi đã thảo luận về các ưu và nhược điểm, chúng tôi đã 7 00:00:13,650 --> 00:00:16,620 thảo luận rằng danh sách liên kết có thể có được lớn hơn và nhỏ hơn, 8 00:00:16,620 --> 00:00:18,630 nhưng chúng chiếm kích thước hơn. 9 00:00:18,630 --> 00:00:22,359 Mảng là đơn giản hơn nhiều để sử dụng, nhưng chúng hạn chế trong nhiều 10 00:00:22,359 --> 00:00:24,900 như chúng ta phải thiết lập kích thước của các mảng ở đầu 11 00:00:24,900 --> 00:00:26,910 và sau đó chúng tôi đang mắc kẹt với nó. 12 00:00:26,910 --> 00:00:30,470 >> Nhưng đó là, chúng tôi đã khá hơn nhiều hết tất cả các chủ đề của chúng tôi 13 00:00:30,470 --> 00:00:33,040 về danh sách và các mảng liên kết. 14 00:00:33,040 --> 00:00:34,950 Hoặc có chúng tôi? 15 00:00:34,950 --> 00:00:37,720 Có lẽ chúng ta có thể làm điều gì đó thậm chí sáng tạo hơn. 16 00:00:37,720 --> 00:00:40,950 Và đó là loại cho vay ý tưởng của một bảng băm. 17 00:00:40,950 --> 00:00:46,680 >> Vì vậy, trong một bảng băm chúng ta sẽ cố gắng kết hợp một mảng với một danh sách liên kết. 18 00:00:46,680 --> 00:00:49,520 Chúng tôi sẽ có những lợi thế của mảng, như truy cập ngẫu nhiên, 19 00:00:49,520 --> 00:00:53,510 việc có thể chỉ cần đi vào mảng 4 yếu tố hoặc mảng phần 8 20 00:00:53,510 --> 00:00:55,560 mà không cần phải lặp qua. 21 00:00:55,560 --> 00:00:57,260 Đó là khá nhanh, phải không? 22 00:00:57,260 --> 00:01:00,714 >> Nhưng chúng tôi cũng muốn có dữ liệu của chúng tôi cấu trúc có thể phát triển và thu nhỏ. 23 00:01:00,714 --> 00:01:02,630 Chúng tôi không cần, chúng tôi không muốn bị hạn chế. 24 00:01:02,630 --> 00:01:04,588 Và chúng tôi muốn có thể thêm và loại bỏ những thứ 25 00:01:04,588 --> 00:01:08,430 rất dễ dàng, mà nếu bạn gọi lại, là rất phức tạp với một mảng. 26 00:01:08,430 --> 00:01:11,650 Và chúng ta có thể gọi đây điều mới một bảng băm. 27 00:01:11,650 --> 00:01:15,190 >> Và nếu được thực hiện một cách chính xác, chúng ta đang loại dùng 28 00:01:15,190 --> 00:01:18,150 những ưu điểm của cả hai dữ liệu cấu trúc mà bạn đã nhìn thấy, 29 00:01:18,150 --> 00:01:19,880 mảng và danh sách liên kết. 30 00:01:19,880 --> 00:01:23,070 Chèn có thể bắt đầu có xu hướng về theta của 1. 31 00:01:23,070 --> 00:01:26,207 Theta, chúng tôi đã không thực sự thảo luận, nhưng theta chỉ là trường hợp trung bình, 32 00:01:26,207 --> 00:01:27,540 những gì đang thực sự xảy ra. 33 00:01:27,540 --> 00:01:29,680 Bạn không phải lúc nào có trường hợp xấu nhất, 34 00:01:29,680 --> 00:01:32,555 và bạn không phải lúc nào cũng sẽ có các trường hợp tốt nhất, vì vậy những gì 35 00:01:32,555 --> 00:01:33,900 kịch bản trung bình? 36 00:01:33,900 --> 00:01:36,500 >> Vâng một chèn trung bình vào một bảng băm 37 00:01:36,500 --> 00:01:39,370 có thể bắt đầu để có được gần với thời gian liên tục. 38 00:01:39,370 --> 00:01:41,570 Và xóa có thể nhận được gần với thời gian liên tục. 39 00:01:41,570 --> 00:01:44,440 Và tra cứu có thể nhận được gần với thời gian liên tục. 40 00:01:44,440 --> 00:01:48,600 That's-- chúng ta không có một dữ liệu cấu trúc nào đó có thể làm điều đó, 41 00:01:48,600 --> 00:01:51,180 và vì vậy điều này đã âm thanh như là một điều khá tuyệt vời. 42 00:01:51,180 --> 00:01:57,010 Chúng tôi đã thực sự giảm thiểu các nhược điểm của mỗi ngày của riêng mình. 43 00:01:57,010 --> 00:01:59,160 >> Để có được hiệu suất này nâng cấp, mặc dù chúng tôi 44 00:01:59,160 --> 00:02:03,580 cần phải suy nghĩ lại cách chúng ta thêm dữ liệu vào cấu trúc. 45 00:02:03,580 --> 00:02:07,380 Cụ thể chúng tôi muốn dữ liệu riêng của mình cho chúng tôi 46 00:02:07,380 --> 00:02:09,725 nơi cần đi trong cấu trúc. 47 00:02:09,725 --> 00:02:12,850 Và nếu chúng ta thì cần phải xem nếu nó trong cấu trúc, nếu chúng ta cần phải tìm thấy nó, 48 00:02:12,850 --> 00:02:16,610 chúng tôi muốn xem xét dữ liệu một lần nữa và có thể có hiệu quả, 49 00:02:16,610 --> 00:02:18,910 bằng cách sử dụng dữ liệu, truy cập ngẫu nhiên cho nó. 50 00:02:18,910 --> 00:02:20,700 Chỉ cần nhìn vào các dữ liệu chúng ta cần phải có 51 00:02:20,700 --> 00:02:25,890 một ý tưởng về nơi chính xác chúng tôi sẽ tìm thấy nó trong bảng băm. 52 00:02:25,890 --> 00:02:28,770 >> Bây giờ các nhược điểm của hàm băm bảng là họ đang thực sự 53 00:02:28,770 --> 00:02:31,770 khá xấu tại đặt hàng hoặc phân loại dữ liệu. 54 00:02:31,770 --> 00:02:34,970 Và trên thực tế, nếu bạn bắt đầu sử dụng chúng để đặt hàng hoặc loại 55 00:02:34,970 --> 00:02:37,990 dữ liệu bạn mất tất cả các lợi thế trước đây bạn 56 00:02:37,990 --> 00:02:40,710 đã về chèn và xóa. 57 00:02:40,710 --> 00:02:44,060 Hiện trở nên gần gũi hơn với theta của n, và chúng tôi đã cơ bản 58 00:02:44,060 --> 00:02:45,530 thụt lùi vào một danh sách liên kết. 59 00:02:45,530 --> 00:02:48,850 Và vì vậy chúng tôi chỉ muốn sử dụng băm bảng nếu chúng ta không quan tâm đến 60 00:02:48,850 --> 00:02:51,490 cho dù dữ liệu được sắp xếp. 61 00:02:51,490 --> 00:02:54,290 Đối với các bối cảnh trong đó bạn sẽ sử dụng chúng trong CS50 62 00:02:54,290 --> 00:02:58,900 có thể bạn không quan tâm rằng các dữ liệu được sắp xếp. 63 00:02:58,900 --> 00:03:03,170 >> Vì vậy, một bảng băm là một sự kết hợp của hai phần riêng biệt 64 00:03:03,170 --> 00:03:04,980 mà chúng ta đã quen thuộc. 65 00:03:04,980 --> 00:03:07,930 Đầu tiên là một chức năng, trong đó chúng ta thường gọi một hàm băm. 66 00:03:07,930 --> 00:03:11,760 Và đó hàm băm sẽ trả lại một số nguyên không âm, mà 67 00:03:11,760 --> 00:03:14,870 chúng ta thường gọi một hashcode, OK? 68 00:03:14,870 --> 00:03:20,230 Cái thứ hai là một mảng, mà là khả năng lưu trữ dữ liệu của các loại chúng tôi 69 00:03:20,230 --> 00:03:22,190 muốn đặt vào cấu trúc dữ liệu. 70 00:03:22,190 --> 00:03:24,310 Chúng tôi sẽ tổ chức off trên liên kết yếu tố danh sách cho doanh nghiệp 71 00:03:24,310 --> 00:03:27,810 và chỉ bắt đầu với những điều cơ bản của một băm bảng để có được đầu của bạn xung quanh nó, 72 00:03:27,810 --> 00:03:30,210 và sau đó chúng tôi sẽ có thể thổi tâm trí của bạn một chút khi chúng ta 73 00:03:30,210 --> 00:03:32,920 kết hợp các mảng và danh sách liên kết với nhau. 74 00:03:32,920 --> 00:03:35,590 >> Ý tưởng cơ bản mặc dù là chúng ta mất một số dữ liệu. 75 00:03:35,590 --> 00:03:37,860 Chúng tôi chạy mà dữ liệu thông qua hàm băm. 76 00:03:37,860 --> 00:03:41,980 Và do đó, các dữ liệu được xử lý và nó phun ra một số, OK? 77 00:03:41,980 --> 00:03:44,890 Và sau đó với con số đó chúng ta chỉ cần lưu trữ các dữ liệu 78 00:03:44,890 --> 00:03:48,930 chúng tôi muốn lưu trữ trong các mảng ở vị trí đó. 79 00:03:48,930 --> 00:03:53,990 Vì thế chúng ta có thể bảng băm này của chuỗi. 80 00:03:53,990 --> 00:03:57,350 Nó có 10 yếu tố trong nó, vì vậy chúng ta có thể phù hợp với 10 chuỗi trong nó. 81 00:03:57,350 --> 00:03:59,320 >> Hãy nói rằng chúng tôi muốn băm John. 82 00:03:59,320 --> 00:04:02,979 Vì vậy, John là dữ liệu chúng tôi muốn chèn vào bảng băm này ở đâu đó. 83 00:04:02,979 --> 00:04:03,770 Nơi nào chúng ta đặt nó? 84 00:04:03,770 --> 00:04:05,728 Vâng điển hình với một mảng cho đến nay chúng ta có thể 85 00:04:05,728 --> 00:04:07,610 sẽ đặt nó trong mảng vị trí 0. 86 00:04:07,610 --> 00:04:09,960 Nhưng bây giờ chúng ta có hàm băm mới này. 87 00:04:09,960 --> 00:04:13,180 >> Và chúng ta hãy nói rằng chúng tôi chạy John thông qua hàm băm này 88 00:04:13,180 --> 00:04:15,417 và nó phun ra 4. 89 00:04:15,417 --> 00:04:17,500 Vâng đó là nơi chúng tôi sẽ muốn đưa John. 90 00:04:17,500 --> 00:04:22,050 Chúng tôi muốn đưa John trong mảng vị trí 4, bởi vì nếu chúng ta băm John again-- 91 00:04:22,050 --> 00:04:23,810 hãy nói rằng sau này chúng tôi muốn tìm kiếm và xem 92 00:04:23,810 --> 00:04:26,960 nếu John tồn tại trong hash này table-- tất cả chúng ta cần phải làm 93 00:04:26,960 --> 00:04:30,310 là chạy nó thông qua các hash cùng chức năng, có được số 4, 94 00:04:30,310 --> 00:04:33,929 và có thể tìm thấy John ngay trong cấu trúc dữ liệu của chúng tôi. 95 00:04:33,929 --> 00:04:34,720 Đó là khá tốt. 96 00:04:34,720 --> 00:04:36,928 >> Hãy nói rằng bây giờ chúng ta làm điều này một lần nữa, chúng tôi muốn băm Paul. 97 00:04:36,928 --> 00:04:39,446 Chúng tôi muốn thêm Paul vào bảng băm này. 98 00:04:39,446 --> 00:04:42,070 Hãy nói rằng lần này chúng tôi chạy Paul qua hàm băm, 99 00:04:42,070 --> 00:04:44,600 hashcode được tạo ra là 6. 100 00:04:44,600 --> 00:04:47,340 Vâng bây giờ chúng ta có thể đưa Paul tại vị trí mảng 6. 101 00:04:47,340 --> 00:04:50,040 Và nếu chúng ta cần phải nhìn lên xem Paul là trong bảng băm này, 102 00:04:50,040 --> 00:04:53,900 tất cả chúng ta cần phải làm là chạy Paul thông qua các hàm băm một lần nữa 103 00:04:53,900 --> 00:04:55,830 và chúng ta sẽ nhận được 6 ra một lần nữa. 104 00:04:55,830 --> 00:04:57,590 >> Và sau đó chúng ta chỉ cần nhìn tại vị trí mảng 6. 105 00:04:57,590 --> 00:04:58,910 Paul là có? 106 00:04:58,910 --> 00:05:00,160 Nếu vậy, anh ấy trong bảng băm. 107 00:05:00,160 --> 00:05:01,875 Paul là không có? 108 00:05:01,875 --> 00:05:03,000 Ông ấy không phải trong bảng băm. 109 00:05:03,000 --> 00:05:05,720 Nó khá dễ hiểu. 110 00:05:05,720 --> 00:05:07,770 >> Bây giờ làm thế nào để bạn xác định một hàm băm? 111 00:05:07,770 --> 00:05:11,460 Cũng có thực sự không có giới hạn số hàm băm có thể. 112 00:05:11,460 --> 00:05:14,350 Trong thực tế có một số thực sự, những người thực sự tốt trên internet. 113 00:05:14,350 --> 00:05:17,560 Có một số thực sự, những người thực sự xấu trên internet. 114 00:05:17,560 --> 00:05:21,080 Nó cũng khá dễ dàng để viết một xấu. 115 00:05:21,080 --> 00:05:23,760 >> Vì vậy, những gì làm nên một tốt hàm băm, phải không? 116 00:05:23,760 --> 00:05:27,280 Vâng một hàm băm tốt nên chỉ sử dụng các dữ liệu đang được băm, 117 00:05:27,280 --> 00:05:29,420 và tất cả các dữ liệu đang được băm. 118 00:05:29,420 --> 00:05:32,500 Vì vậy, chúng tôi không muốn sử dụng anything-- chúng ta không kết hợp bất cứ điều gì 119 00:05:32,500 --> 00:05:35,560 khác ngoài các dữ liệu. 120 00:05:35,560 --> 00:05:37,080 Và chúng tôi muốn sử dụng tất cả các dữ liệu. 121 00:05:37,080 --> 00:05:39,830 Chúng tôi không muốn chỉ cần sử dụng một mảnh của nó, chúng tôi muốn sử dụng tất cả của nó. 122 00:05:39,830 --> 00:05:41,710 Một hàm băm nên cũng được xác định. 123 00:05:41,710 --> 00:05:42,550 Điều đó có nghĩa là gì? 124 00:05:42,550 --> 00:05:46,200 Cũng có nghĩa là mỗi lần chúng tôi vượt qua các mảnh cùng chính xác của dữ liệu 125 00:05:46,200 --> 00:05:50,040 vào hàm băm chúng tôi luôn có được hashcode cùng ra. 126 00:05:50,040 --> 00:05:52,870 Nếu tôi vượt qua John vào hàm băm tôi nhận ra 4. 127 00:05:52,870 --> 00:05:56,110 Tôi sẽ có thể làm điều đó 10.000 lần và tôi sẽ luôn luôn nhận được 4. 128 00:05:56,110 --> 00:06:00,810 Vì vậy, không có con số ngẫu nhiên hiệu quả có thể được tham gia vào băm của chúng tôi tables-- 129 00:06:00,810 --> 00:06:02,750 trong hàm băm của chúng tôi. 130 00:06:02,750 --> 00:06:05,750 >> Một hàm băm cũng nên thống nhất phân phối dữ liệu. 131 00:06:05,750 --> 00:06:09,700 Nếu mỗi khi bạn chạy các dữ liệu thông qua các hàm băm bạn nhận được hashcode 0, 132 00:06:09,700 --> 00:06:11,200 đó có lẽ không tuyệt vời như vậy, phải không? 133 00:06:11,200 --> 00:06:14,600 Bạn có thể muốn lớn một loạt các mã băm. 134 00:06:14,600 --> 00:06:17,190 Cũng có những thứ có thể lây lan ra khắp bàn. 135 00:06:17,190 --> 00:06:23,210 Và cũng có thể nó sẽ là tuyệt vời nếu thực sự dữ liệu tương tự, như John và Jonathan, 136 00:06:23,210 --> 00:06:26,320 có thể được trải ra để cân nhắc địa điểm khác nhau trong bảng băm. 137 00:06:26,320 --> 00:06:28,750 Đó sẽ là một lợi thế tốt đẹp. 138 00:06:28,750 --> 00:06:31,250 >> Dưới đây là một ví dụ về một hàm băm. 139 00:06:31,250 --> 00:06:33,150 Tôi đã viết này lên trước đó. 140 00:06:33,150 --> 00:06:35,047 Nó không phải là một đặc biệt hàm băm tốt 141 00:06:35,047 --> 00:06:37,380 vì những lý do không thực sự chịu đi vào ngay bây giờ. 142 00:06:37,380 --> 00:06:41,040 Nhưng bạn có thấy những gì đang xảy ra ở đây? 143 00:06:41,040 --> 00:06:44,420 Nó có vẻ như chúng ta đang khai báo một biến gọi là tiền và thiết lập nó bằng 0. 144 00:06:44,420 --> 00:06:50,010 Và sau đó dường như tôi đang làm một cái gì đó miễn là strstr [j] là không bằng nhau 145 00:06:50,010 --> 00:06:52,490 để dấu gạch chéo ngược 0. 146 00:06:52,490 --> 00:06:54,870 Tôi đang làm gì ở đó? 147 00:06:54,870 --> 00:06:57,440 >> Điều này về cơ bản là giống nhau cách thực hiện [? strl?] 148 00:06:57,440 --> 00:06:59,773 và phát hiện khi bạn đã đạt đến kết thúc của chuỗi. 149 00:06:59,773 --> 00:07:02,480 Vì vậy, tôi không cần phải thực sự tính toán chiều dài của chuỗi, 150 00:07:02,480 --> 00:07:05,640 Tôi chỉ sử dụng khi tôi nhấn backslash 0 nhân vật tôi biết 151 00:07:05,640 --> 00:07:07,185 Tôi đã đạt đến kết thúc của chuỗi. 152 00:07:07,185 --> 00:07:09,560 Và sau đó tôi sẽ giữ lặp lại thông qua chuỗi, 153 00:07:09,560 --> 00:07:15,310 thêm strstr [j] để tổng hợp, và sau đó tại cuối ngày sẽ trở về sum mod 154 00:07:15,310 --> 00:07:16,200 HASH_MAX. 155 00:07:16,200 --> 00:07:18,700 >> Về cơ bản tất cả các hash này chức năng đang làm là thêm lên 156 00:07:18,700 --> 00:07:23,450 tất cả các giá trị ASCII của chuỗi của tôi, và sau đó nó 157 00:07:23,450 --> 00:07:26,390 trả lại một số hashcode modded của HASH_MAX. 158 00:07:26,390 --> 00:07:29,790 Đó có lẽ là kích thước các mảng của tôi, phải không? 159 00:07:29,790 --> 00:07:33,160 Tôi không muốn nhận được băm mã nếu mảng của tôi có kích thước 10, 160 00:07:33,160 --> 00:07:35,712 Tôi không muốn là nhận được ra mã băm 11, 12, 161 00:07:35,712 --> 00:07:38,690 13 tuổi, tôi không thể đặt mọi thứ vào những vị trí của mảng, 162 00:07:38,690 --> 00:07:39,790 đó sẽ là bất hợp pháp. 163 00:07:39,790 --> 00:07:42,130 Tôi bị một lỗi phân khúc. 164 00:07:42,130 --> 00:07:45,230 >> Bây giờ đây là một cách nhanh chóng sang một bên. 165 00:07:45,230 --> 00:07:48,470 Nói chung bạn có thể sẽ không muốn viết hàm băm của riêng bạn. 166 00:07:48,470 --> 00:07:50,997 Nó thực sự là một chút một nghệ thuật, không phải là một khoa học. 167 00:07:50,997 --> 00:07:52,580 Và có rất nhiều mà đi vào chúng. 168 00:07:52,580 --> 00:07:55,288 Internet, như tôi đã nói, có đầy đủ của hàm băm thực sự tốt, 169 00:07:55,288 --> 00:07:58,470 và bạn nên sử dụng internet để tìm các hàm băm vì nó thực sự 170 00:07:58,470 --> 00:08:03,230 chỉ cần loại một không cần thiết lãng phí thời gian để tạo của riêng bạn. 171 00:08:03,230 --> 00:08:05,490 >> Bạn có thể viết cái đơn giản cho mục đích thử nghiệm. 172 00:08:05,490 --> 00:08:08,323 Nhưng khi bạn thực sự sẽ bắt đầu băm dữ liệu và lưu trữ nó 173 00:08:08,323 --> 00:08:10,780 vào một bảng băm bạn có lẽ sẽ muốn 174 00:08:10,780 --> 00:08:14,580 sử dụng một số chức năng đã được tạo ra cho bạn, mà tồn tại trên internet. 175 00:08:14,580 --> 00:08:17,240 Nếu bạn chỉ cần nhớ để trích dẫn nguồn của bạn. 176 00:08:17,240 --> 00:08:21,740 Không có lý do để ăn cắp bất cứ thứ gì ở đây. 177 00:08:21,740 --> 00:08:25,370 >> Cộng đồng khoa học máy tính là chắc chắn ngày càng tăng, và thực sự giá trị 178 00:08:25,370 --> 00:08:28,796 mã nguồn mở, và nó thực sự quan trọng để trích dẫn nguồn của bạn để mọi người 179 00:08:28,796 --> 00:08:30,670 có thể được ghi công cho công việc mà họ đang 180 00:08:30,670 --> 00:08:32,312 làm cho lợi ích của cộng đồng. 181 00:08:32,312 --> 00:08:34,020 Vì vậy, luôn luôn có sure-- và không chỉ cho hash 182 00:08:34,020 --> 00:08:37,270 chức năng, nhưng nói chung khi bạn sử dụng mã từ một nguồn bên ngoài, 183 00:08:37,270 --> 00:08:38,299 luôn luôn trích dẫn nguồn của bạn. 184 00:08:38,299 --> 00:08:43,500 Cung cấp tín dụng cho người đã làm một số công việc, do đó bạn không phải. 185 00:08:43,500 --> 00:08:46,720 >> OK như vậy chúng ta hãy xem lại này bảng băm cho một thứ hai. 186 00:08:46,720 --> 00:08:48,780 Đây là nơi chúng tôi rời off sau khi chúng ta chèn 187 00:08:48,780 --> 00:08:53,300 John và Paul vào bảng băm này. 188 00:08:53,300 --> 00:08:55,180 Bạn có thấy một vấn đề ở đây? 189 00:08:55,180 --> 00:08:58,410 Bạn có thể thấy hai. 190 00:08:58,410 --> 00:09:02,240 Nhưng đặc biệt, làm bạn xem lại vấn đề này? 191 00:09:02,240 --> 00:09:06,770 >> Nếu tôi băm gì Ringo, và nó Hóa ra sau khi chế biến 192 00:09:06,770 --> 00:09:14,000 rằng dữ liệu thông qua các hàm băm Ringo cũng tạo ra hashcode 6. 193 00:09:14,000 --> 00:09:16,810 Tôi đã nhận được dữ liệu ở hashcode-- mảng vị trí 6. 194 00:09:16,810 --> 00:09:22,000 Vì vậy, nó có thể có được một chút của một vấn đề đối với tôi bây giờ, phải không? 195 00:09:22,000 --> 00:09:23,060 >> Chúng tôi gọi đây là một vụ va chạm. 196 00:09:23,060 --> 00:09:26,460 Và các vụ va chạm xảy ra khi hai mẩu dữ liệu chạy qua cùng bảng băm 197 00:09:26,460 --> 00:09:29,200 chức năng mang lại hashcode cùng. 198 00:09:29,200 --> 00:09:32,850 Có lẽ chúng ta vẫn muốn có được cả mẩu dữ liệu vào bảng băm, 199 00:09:32,850 --> 00:09:36,330 nếu không chúng tôi sẽ không được chạy Ringo tự ý thông qua các hàm băm. 200 00:09:36,330 --> 00:09:40,870 Chúng ta có lẽ muốn có được Ringo vào mảng đó. 201 00:09:40,870 --> 00:09:46,070 >> Làm thế nào để chúng tôi làm điều đó, mặc dù nếu ông và Paul cả năng suất hashcode 6? 202 00:09:46,070 --> 00:09:49,520 Chúng tôi không muốn ghi đè Paul, chúng tôi muốn Paul có mặt ở đó quá. 203 00:09:49,520 --> 00:09:52,790 Vì vậy, chúng ta cần phải tìm một cách để có được các yếu tố vào bảng băm 204 00:09:52,790 --> 00:09:56,550 vẫn còn lưu giữ nhanh của chúng tôi chèn và nhanh chóng nhìn lên. 205 00:09:56,550 --> 00:10:01,350 Và một cách để đối phó với nó là để làm một cái gì đó gọi là tuyến tính thăm dò. 206 00:10:01,350 --> 00:10:04,170 >> Sử dụng phương pháp này nếu chúng ta có một va chạm, tốt, chúng ta làm gì? 207 00:10:04,170 --> 00:10:08,580 Vâng, chúng tôi không thể đưa anh ta trong mảng vị trí 6, hoặc bất cứ điều gì hashcode đã được tạo ra, 208 00:10:08,580 --> 00:10:10,820 chúng ta hãy đặt anh ở hashcode cộng thêm 1. 209 00:10:10,820 --> 00:10:13,670 Và nếu đó là đầy đủ cho phép của đưa anh vào hashcode cộng 2. 210 00:10:13,670 --> 00:10:17,420 Lợi ích của việc này là nếu anh ta không chính xác nơi chúng tôi nghĩ rằng ông là, 211 00:10:17,420 --> 00:10:20,850 và chúng ta phải bắt đầu tìm kiếm, có lẽ chúng ta không cần phải đi quá xa. 212 00:10:20,850 --> 00:10:23,900 Có lẽ chúng ta không cần phải tìm kiếm tất cả các yếu tố n của bảng băm. 213 00:10:23,900 --> 00:10:25,790 Có lẽ chúng ta phải tìm kiếm một vài trong số họ. 214 00:10:25,790 --> 00:10:30,680 >> Và vì vậy chúng tôi vẫn chăm sóc theo hướng mà trường hợp trung bình là gần 1 vs 215 00:10:30,680 --> 00:10:34,280 gần n, vì vậy có lẽ đó sẽ làm việc. 216 00:10:34,280 --> 00:10:38,010 Vì vậy, chúng ta hãy xem cách này có thể làm việc trong thực tế. 217 00:10:38,010 --> 00:10:41,460 Và chúng ta hãy xem nếu có thể chúng ta có thể phát hiện các vấn đề có thể xảy ra ở đây. 218 00:10:41,460 --> 00:10:42,540 >> Hãy nói rằng chúng tôi băm Bart. 219 00:10:42,540 --> 00:10:45,581 Vì vậy, bây giờ chúng tôi đang đi để chạy một bộ mới của chuỗi thông qua các hàm băm, 220 00:10:45,581 --> 00:10:48,460 và chúng tôi chạy Bart qua băm chức năng, chúng tôi nhận được hashcode 6. 221 00:10:48,460 --> 00:10:52,100 Chúng ta hãy xem, chúng ta thấy là 6 trống rỗng, vì vậy chúng tôi có thể đặt Bart có. 222 00:10:52,100 --> 00:10:55,410 >> Bây giờ chúng ta băm Lisa và rằng cũng tạo ra hashcode 6. 223 00:10:55,410 --> 00:10:58,330 Vâng bây giờ mà chúng tôi đang sử dụng này phương pháp, chúng tôi bắt đầu vào lúc 6 tuyến tính thăm dò, 224 00:10:58,330 --> 00:10:59,330 chúng ta thấy rằng 6 là đầy đủ. 225 00:10:59,330 --> 00:11:00,990 Chúng tôi không thể đặt Lisa trong 6. 226 00:11:00,990 --> 00:11:02,090 Vì vậy, nơi nào chúng ta đi? 227 00:11:02,090 --> 00:11:03,280 Hãy đi đến 7. 228 00:11:03,280 --> 00:11:04,610 7 sản phẩm nào, vì vậy mà các công trình. 229 00:11:04,610 --> 00:11:06,510 Vì vậy, chúng ta hãy đặt Lisa có. 230 00:11:06,510 --> 00:11:10,200 >> Bây giờ chúng ta băm Homer và chúng tôi có được 7. 231 00:11:10,200 --> 00:11:13,380 OK, chúng tôi cũng biết rằng 7 đầy đủ bây giờ, vì vậy chúng tôi không thể đặt Homer có. 232 00:11:13,380 --> 00:11:14,850 Vì vậy, chúng ta hãy đi đến 8. 233 00:11:14,850 --> 00:11:15,664 8 có sẵn? 234 00:11:15,664 --> 00:11:18,330 Yeah, và gần 8 thành 7, do đó, nếu chúng ta phải bắt đầu tìm kiếm chúng tôi 235 00:11:18,330 --> 00:11:20,020 sẽ không phải đi quá xa. 236 00:11:20,020 --> 00:11:22,860 Và như vậy chúng ta hãy đặt Homer lúc 8. 237 00:11:22,860 --> 00:11:25,151 >> Bây giờ chúng ta băm Maggie và trả về 3, cảm ơn lòng tốt 238 00:11:25,151 --> 00:11:26,650 chúng tôi có thể chỉ cần đặt Maggie có. 239 00:11:26,650 --> 00:11:29,070 Chúng tôi không phải làm bất kỳ loại thăm dò cho rằng. 240 00:11:29,070 --> 00:11:32,000 Bây giờ chúng ta băm Marge, và Marge cũng trả 6. 241 00:11:32,000 --> 00:11:39,560 >> Vâng 6 là đầy đủ, 7 là đầy đủ, 8 là đầy đủ, 9, tất cả phải cảm tạ Thiên Chúa, 9 là trống rỗng. 242 00:11:39,560 --> 00:11:41,600 Tôi có thể đặt Marge lúc 9. 243 00:11:41,600 --> 00:11:45,280 Đã chúng tôi có thể thấy rằng chúng ta đang bắt đầu có vấn đề này mà hiện nay chúng tôi 244 00:11:45,280 --> 00:11:48,780 bắt đầu căng ra loại điều của xa mã băm của họ. 245 00:11:48,780 --> 00:11:52,960 Và đó theta của 1, trung bình mà Nếu là hằng số thời gian, 246 00:11:52,960 --> 00:11:56,560 đang bắt đầu để có được một chút more-- bắt đầu có xu hướng nhiều hơn một chút 247 00:11:56,560 --> 00:11:58,050 hướng theta của n. 248 00:11:58,050 --> 00:12:01,270 Chúng tôi đang bắt đầu đánh mất điều đó lợi thế của bảng băm. 249 00:12:01,270 --> 00:12:03,902 >> Vấn đề này chúng ta chỉ nhìn thấy là một cái gì đó gọi là clustering. 250 00:12:03,902 --> 00:12:06,360 Và những gì là thực sự xấu về Clustering là một khi bạn bây giờ 251 00:12:06,360 --> 00:12:09,606 có hai yếu tố đó là mặt bằng bên kia nó làm cho nó thậm chí nhiều khả năng, 252 00:12:09,606 --> 00:12:11,480 bạn có gấp đôi cơ hội, rằng bạn đang đi 253 00:12:11,480 --> 00:12:13,516 có va chạm khác với cụm đó, 254 00:12:13,516 --> 00:12:14,890 và các cluster sẽ phát triển một. 255 00:12:14,890 --> 00:12:19,640 Và bạn sẽ tiếp tục tăng trưởng và phát triển khả năng của bạn có một vụ va chạm. 256 00:12:19,640 --> 00:12:24,470 Và cuối cùng nó chỉ là xấu như không phân loại dữ liệu ở tất cả. 257 00:12:24,470 --> 00:12:27,590 >> Các vấn đề khác là mặc dù chúng tôi vẫn còn, và cho đến nay cho đến thời điểm này, 258 00:12:27,590 --> 00:12:30,336 chúng tôi đã chỉ được loại hiểu biết những gì một bảng băm là, 259 00:12:30,336 --> 00:12:31,960 chúng ta vẫn chỉ có chỗ cho 10 dây. 260 00:12:31,960 --> 00:12:37,030 Nếu chúng ta muốn tiếp tục băm các công dân của Springfield, 261 00:12:37,030 --> 00:12:38,790 chúng ta chỉ có thể nhận được 10 trong số họ trong đó. 262 00:12:38,790 --> 00:12:42,619 Và nếu chúng ta cố gắng và thêm một lần thứ 11 hoặc 12, chúng ta không có một nơi để đặt chúng. 263 00:12:42,619 --> 00:12:45,660 Chúng tôi chỉ có thể quay xung quanh trong vòng tròn cố gắng để tìm một chỗ trống, 264 00:12:45,660 --> 00:12:49,000 và chúng tôi có thể bị mắc kẹt trong một vòng lặp vô hạn. 265 00:12:49,000 --> 00:12:51,810 >> Vì vậy, loại này mượn ý tưởng của một cái gì đó gọi là chuỗi. 266 00:12:51,810 --> 00:12:55,790 Và đây là nơi mà chúng ta sẽ mang lại danh sách liên kết lại thành hình ảnh. 267 00:12:55,790 --> 00:13:01,300 Điều gì nếu thay vì lưu trữ chỉ các dữ liệu chính nó trong mảng, 268 00:13:01,300 --> 00:13:04,471 mọi phần tử của mảng có thể giữ nhiều mẩu dữ liệu? 269 00:13:04,471 --> 00:13:05,970 Vâng đó không có ý nghĩa, phải không? 270 00:13:05,970 --> 00:13:09,280 Chúng ta biết rằng một mảng chỉ có thể hold-- mỗi phần tử của một mảng 271 00:13:09,280 --> 00:13:12,930 chỉ có thể giữ một mảnh các dữ liệu của các kiểu dữ liệu. 272 00:13:12,930 --> 00:13:16,750 >> Nhưng nếu những gì mà kiểu dữ liệu là một danh sách liên kết, phải không? 273 00:13:16,750 --> 00:13:19,830 Vì vậy, những gì nếu mỗi phần tử của mảng là 274 00:13:19,830 --> 00:13:22,790 một con trỏ đến đầu của một danh sách liên kết? 275 00:13:22,790 --> 00:13:24,680 Và sau đó chúng ta có thể xây dựng những danh sách liên kết 276 00:13:24,680 --> 00:13:27,120 và phát triển chúng tùy tiện, vì danh sách liên kết cho phép 277 00:13:27,120 --> 00:13:32,090 chúng ta lớn lên và thu nhỏ hơn rất nhiều linh hoạt hơn so với một mảng nào. 278 00:13:32,090 --> 00:13:34,210 Vì vậy, nếu chúng ta bây giờ sử dụng, chúng tôi tận dụng điều này, phải không? 279 00:13:34,210 --> 00:13:37,760 Chúng tôi bắt đầu phát triển các chuỗi ra khỏi các vị trí mảng. 280 00:13:37,760 --> 00:13:40,740 >> Bây giờ chúng ta có thể phù hợp với một vô hạn lượng dữ liệu, hoặc phải là vô hạn, 281 00:13:40,740 --> 00:13:44,170 một số lượng tùy ý dữ liệu, vào bảng băm của chúng tôi 282 00:13:44,170 --> 00:13:47,760 mà không bao giờ chạy vào các vấn đề của vụ va chạm. 283 00:13:47,760 --> 00:13:50,740 Chúng tôi cũng đã loại bỏ phân nhóm bằng cách làm này. 284 00:13:50,740 --> 00:13:54,380 Và cũng chúng tôi biết rằng khi chúng ta chèn vào một danh sách liên kết, nếu bạn gọi lại 285 00:13:54,380 --> 00:13:57,779 từ video của chúng tôi trên danh sách liên kết đơn lẻ danh sách liên kết và danh sách liên kết kép, 286 00:13:57,779 --> 00:13:59,070 đó là một thời gian hoạt động liên tục. 287 00:13:59,070 --> 00:14:00,710 Chúng tôi chỉ cần thêm vào phía trước. 288 00:14:00,710 --> 00:14:04,400 >> Và cho cái nhìn lên, cũng chúng tôi biết mà nhìn lên trong một danh sách liên kết 289 00:14:04,400 --> 00:14:05,785 có thể là một vấn đề, phải không? 290 00:14:05,785 --> 00:14:07,910 Chúng ta phải tìm kiếm thông qua nó từ đầu đến cuối. 291 00:14:07,910 --> 00:14:10,460 Không ngẫu nhiên truy cập vào một danh sách liên kết. 292 00:14:10,460 --> 00:14:15,610 Nhưng nếu thay vì có một liên kết danh sách nơi mà một tra cứu sẽ là O của n, 293 00:14:15,610 --> 00:14:19,590 Hiện tại chúng tôi có 10 danh sách liên kết, hoặc 1.000 danh sách liên kết, 294 00:14:19,590 --> 00:14:24,120 bây giờ nó là O của n chia cho 10, hoặc O của n khi chia cho 1000. 295 00:14:24,120 --> 00:14:26,940 >> Và trong khi chúng tôi đang nói chuyện lý thuyết về sự phức tạp 296 00:14:26,940 --> 00:14:30,061 chúng ta bỏ qua các hằng số, trong thực tế thế giới những điều thực sự quan trọng, 297 00:14:30,061 --> 00:14:30,560 bên phải? 298 00:14:30,560 --> 00:14:33,080 Chúng tôi thực sự sẽ thông báo rằng điều này sẽ xảy ra 299 00:14:33,080 --> 00:14:36,610 chạy 10 lần nhanh hơn, hoặc nhanh hơn 1.000 lần, 300 00:14:36,610 --> 00:14:41,570 bởi vì chúng tôi đang phân phối một dài chuỗi trên 1.000 chuỗi nhỏ hơn. 301 00:14:41,570 --> 00:14:45,090 Và do đó, mỗi lần chúng tôi phải tìm kiếm thông qua một trong những chuỗi chúng ta có thể 302 00:14:45,090 --> 00:14:50,290 bỏ qua 999 chuỗi chúng ta không quan tâm về, và chỉ cần tìm kiếm một. 303 00:14:50,290 --> 00:14:53,220 >> Mà là trên trung bình thể ngắn hơn khoảng 1.000 lần. 304 00:14:53,220 --> 00:14:56,460 Và vì vậy chúng tôi vẫn là loại chăm sóc đối với trường hợp này trung bình 305 00:14:56,460 --> 00:15:01,610 của thời gian là không đổi, nhưng chỉ bởi vì chúng ta đang tận dụng 306 00:15:01,610 --> 00:15:03,730 phân chia bởi một số yếu tố không đổi rất lớn. 307 00:15:03,730 --> 00:15:05,804 Chúng ta hãy xem làm thế nào điều này có thể thực sự nhìn mặc dù. 308 00:15:05,804 --> 00:15:08,720 Vì vậy, đây là bảng băm chúng tôi đã có trước khi chúng tôi tuyên bố một bảng băm 309 00:15:08,720 --> 00:15:10,270 là khả năng lưu trữ 10 dây. 310 00:15:10,270 --> 00:15:11,728 Chúng tôi sẽ không làm điều đó nữa. 311 00:15:11,728 --> 00:15:13,880 Chúng tôi đã biết hạn chế của phương pháp đó. 312 00:15:13,880 --> 00:15:20,170 Bây giờ bảng băm của chúng tôi sẽ là một mảng của 10 nút, con trỏ 313 00:15:20,170 --> 00:15:22,120 cho người đứng đầu của danh sách liên kết. 314 00:15:22,120 --> 00:15:23,830 >> Và ngay bây giờ nó là null. 315 00:15:23,830 --> 00:15:26,170 Mỗi một trong những 10 con trỏ là null. 316 00:15:26,170 --> 00:15:29,870 Không có gì ở chúng tôi băm bảng ngay bây giờ. 317 00:15:29,870 --> 00:15:32,690 >> Bây giờ chúng ta hãy bắt đầu đưa một số thứ vào bảng băm này. 318 00:15:32,690 --> 00:15:35,440 Và chúng ta hãy xem làm thế nào phương pháp này là sẽ có lợi cho chúng ta một chút. 319 00:15:35,440 --> 00:15:36,760 Bây giờ chúng ta băm Joey. 320 00:15:36,760 --> 00:15:40,210 Chúng tôi sẽ sẽ chạy chuỗi Joey qua một hàm băm và chúng tôi trở lại 6. 321 00:15:40,210 --> 00:15:41,200 Vâng chúng ta làm gì bây giờ? 322 00:15:41,200 --> 00:15:44,090 >> Vâng bây giờ làm việc với các danh sách liên kết, chúng tôi không làm việc với mảng. 323 00:15:44,090 --> 00:15:45,881 Và khi chúng tôi đang làm việc với danh sách liên kết chúng tôi 324 00:15:45,881 --> 00:15:49,790 biết chúng ta cần phải bắt đầu tự động phân bổ không gian và xây dựng dây chuyền. 325 00:15:49,790 --> 00:15:54,020 Đó là loại how-- những là cốt lõi các yếu tố của việc xây dựng một danh sách liên kết. 326 00:15:54,020 --> 00:15:57,670 Vì vậy, hãy động phân bổ không gian cho Joey, 327 00:15:57,670 --> 00:16:00,390 và sau đó chúng ta hãy thêm anh ấy vào chuỗi. 328 00:16:00,390 --> 00:16:03,170 >> Vì vậy, bây giờ nhìn những gì chúng tôi đã làm. 329 00:16:03,170 --> 00:16:06,440 Khi chúng ta băm Joey chúng tôi đã nhận hashcode 6. 330 00:16:06,440 --> 00:16:11,790 Bây giờ con trỏ tại vị trí mảng 6 chỉ vào đầu của một danh sách liên kết, 331 00:16:11,790 --> 00:16:14,900 và ngay bây giờ nó chỉ yếu tố của một danh sách liên kết. 332 00:16:14,900 --> 00:16:18,350 Và các nút trong đó danh sách liên kết là Joey. 333 00:16:18,350 --> 00:16:22,300 >> Vì vậy, nếu chúng ta cần phải nhìn lên Joey sau đó, chúng ta chỉ băm Joey một lần nữa, 334 00:16:22,300 --> 00:16:26,300 chúng tôi nhận được 6 lần nữa bởi vì chúng tôi hàm băm là xác định. 335 00:16:26,300 --> 00:16:30,400 Và sau đó chúng tôi bắt đầu từ đầu của danh sách liên kết chỉ 336 00:16:30,400 --> 00:16:33,360 đến vị trí của mảng 6, và chúng tôi có thể lặp 337 00:16:33,360 --> 00:16:35,650 qua đó cố gắng tìm Joey. 338 00:16:35,650 --> 00:16:37,780 Và nếu chúng ta xây dựng của chúng tôi băm bảng hiệu quả, 339 00:16:37,780 --> 00:16:41,790 và hàm băm của chúng tôi hiệu quả để phân phối dữ liệu tốt, 340 00:16:41,790 --> 00:16:45,770 trung bình mỗi người trong những liên kết danh sách tại mỗi địa điểm mảng 341 00:16:45,770 --> 00:16:50,110 sẽ là 1/10 kích thước của nếu chúng ta chỉ có nó như là một lớn duy nhất 342 00:16:50,110 --> 00:16:51,650 danh sách liên kết với tất cả mọi thứ trong đó. 343 00:16:51,650 --> 00:16:55,670 >> Nếu chúng tôi phân phối là rất lớn liên quan danh sách trên 10 danh sách liên kết 344 00:16:55,670 --> 00:16:57,760 mỗi danh sách sẽ là 1/10 kích thước. 345 00:16:57,760 --> 00:17:01,432 Và như vậy 10 lần nhanh hơn để tìm kiếm thông qua. 346 00:17:01,432 --> 00:17:02,390 Vì vậy, hãy làm điều này một lần nữa. 347 00:17:02,390 --> 00:17:04,290 Bây giờ chúng ta băm Ross. 348 00:17:04,290 --> 00:17:07,540 >> Và giả Ross, khi chúng ta làm điều đó mã băm chúng tôi nhận lại là 2. 349 00:17:07,540 --> 00:17:10,630 Vâng bây giờ chúng tôi tự động phân bổ một nút mới, chúng tôi đặt Ross ở nút đó, 350 00:17:10,630 --> 00:17:14,900 và chúng tôi nói bây giờ mảng vị trí 2, thay vì chỉ để null, 351 00:17:14,900 --> 00:17:18,579 chỉ vào đầu của một liên kết danh sách mà chỉ có nút là Ross. 352 00:17:18,579 --> 00:17:22,660 Và chúng ta có thể làm thêm một thời gian này, chúng tôi có thể băm Rachel và nhận được hashcode 4. 353 00:17:22,660 --> 00:17:25,490 malloc một nút mới, đưa Rachel trong nút, và nói một vị trí mảng 354 00:17:25,490 --> 00:17:27,839 4 bây giờ chỉ vào đầu của một danh sách liên kết mà 355 00:17:27,839 --> 00:17:31,420 chỉ yếu tố sẽ xảy ra là Rachel. 356 00:17:31,420 --> 00:17:33,470 >> OK, nhưng những gì sẽ xảy ra nếu chúng ta có một vụ va chạm? 357 00:17:33,470 --> 00:17:38,560 Hãy xem cách chúng tôi xử lý va chạm sử dụng các phương pháp chaining riêng biệt. 358 00:17:38,560 --> 00:17:39,800 Hãy băm Phoebe. 359 00:17:39,800 --> 00:17:41,094 Chúng tôi nhận được hashcode 6. 360 00:17:41,094 --> 00:17:44,010 Trong ví dụ trước, chúng tôi đã chỉ lưu trữ các chuỗi trong mảng. 361 00:17:44,010 --> 00:17:45,980 Đây là một vấn đề. 362 00:17:45,980 --> 00:17:48,444 >> Chúng tôi không muốn clobber Joey, và chúng tôi đã đã 363 00:17:48,444 --> 00:17:51,110 thấy rằng chúng ta có thể nhận được một số phân nhóm vấn đề nếu chúng ta cố gắng và bước 364 00:17:51,110 --> 00:17:52,202 thông qua và thăm dò. 365 00:17:52,202 --> 00:17:54,660 Nhưng nếu chúng ta chỉ cần loại điều trị này theo cùng một cách, phải không? 366 00:17:54,660 --> 00:17:57,440 Nó giống như thêm một phần tử cho người đứng đầu của một danh sách liên kết. 367 00:17:57,440 --> 00:18:00,220 Hãy gian chỉ malloc cho Phoebe. 368 00:18:00,220 --> 00:18:04,764 >> Chúng tôi sẽ nói con trỏ trỏ tới của Phoebe cho người đứng đầu cũ của danh sách liên kết, 369 00:18:04,764 --> 00:18:07,180 và sau đó 6 chỉ trỏ tới đứng đầu mới của danh sách liên kết. 370 00:18:07,180 --> 00:18:10,150 Và bây giờ nhìn, chúng tôi đã thay đổi Phoebe trong. 371 00:18:10,150 --> 00:18:14,210 Bây giờ chúng ta có thể lưu trữ hai các yếu tố với hashcode 6, 372 00:18:14,210 --> 00:18:17,170 và chúng tôi không có bất kỳ vấn đề. 373 00:18:17,170 --> 00:18:20,147 >> Đó là khá nhiều tất cả có tới loạt. 374 00:18:20,147 --> 00:18:21,980 Và chắc chắn là chaining phương pháp phù hợp 375 00:18:21,980 --> 00:18:27,390 sẽ có hiệu quả nhất cho bạn nếu bạn đang lưu trữ dữ liệu trong một bảng băm. 376 00:18:27,390 --> 00:18:30,890 Nhưng sự kết hợp của mảng và danh sách liên kết 377 00:18:30,890 --> 00:18:36,080 với nhau để tạo thành một bảng băm thực sự cải thiện đáng kể khả năng của bạn 378 00:18:36,080 --> 00:18:40,550 để lưu trữ một lượng lớn dữ liệu, và rất nhanh chóng và hiệu quả tìm kiếm 379 00:18:40,550 --> 00:18:41,630 thông qua các dữ liệu đó. 380 00:18:41,630 --> 00:18:44,150 >> Vẫn có một nhiều hơn cấu trúc dữ liệu ra có 381 00:18:44,150 --> 00:18:48,700 mà thậm chí có thể là một chút tốt hơn về bảo đảm 382 00:18:48,700 --> 00:18:51,920 rằng chúng ta chèn, xóa, và nhìn lên lần thậm chí còn nhanh hơn. 383 00:18:51,920 --> 00:18:55,630 Và chúng ta sẽ thấy rằng trong một đoạn video trên cố gắng. 384 00:18:55,630 --> 00:18:58,930 Tôi Doug Lloyd, đây là CS50. 385 00:18:58,930 --> 00:19:00,214