Ⅰ 數據結構演算法
鏈表-》棧-》二叉樹-》圖這樣的順序來學習這門課程
1.找c代碼,看懂,自己寫
2.有很多經典的演算法,我以前學的時候也看數據結構1800,考研用書,比較好的,把基本的數據結構這快的操作都包含進去了
3.如果你需要,在看看演算法導論。
1.是關鍵,2,3都是補充。如果只想過了這門課,上課認真聽就好了,把最最基本的鏈表,棧,樹的遞歸遍歷用c寫寫就ok了。
Ⅱ 數據結構和演算法有什麼關系數據結構就是演算法嗎
首先你要弄清楚數據結構是什麼?數據結構呢其實就是一種存儲數據之間的邏輯結構:比如我們學過的線性結構:順序表啦,鏈表啦;層次結構:樹啦。合適的數據結構可以帶來更高的運行效率和存儲效率,與相應解決實際問題演算法的適應性也就越高,這也就是為什麼一些演算法指定了數據存儲必須以某種特定的數據結才行。一般都是根據合適的數據結構來設計演算法,而不是根據演算法來設計數據結構。
演算法和數據結構往往是互不分開的。離開了演算法,數據結構就顯得毫無意義,而沒有了數據結構演算法就沒有實現的條件。良好的數據結構思想就是一種高效的演算法,但是數據結構不等於演算法。只有當數據結構用於處理某個特定問題類型的時候,數據結構才會體現為演算法。要想細致的了解,就要多看書,因為這東西畢竟發展了那麼多年,一兩句話是說不清楚的。想知道更多的數據結構與演算法知識嗎?可以去了解一下小碼哥李明傑。
Ⅲ 演算法和數據結構
給你貼USACO這一題的通關報告,英文的啊:
We use a recursive complete search to simply test all boards. The search proceeds by trying to put one checker in each row. We keep track of which columns and diagonals already have checkers on them in the "col", "updiag", and "downdiag" arrays.
Since we generate solutions in increasing order, we record the first 3 in the "sol" array.
Symmetry enables us to count the first half of the solutions double and avoid calculating the second half. An exception happens when N is odd; the odd row needs to be counted once.
The N>6 lines get the program out of trouble when N==6, because at that point, the first 3 solutions include one of the symmetric answers.
Since we number rows from 0 to N-1 rather than 1 to N, we need to add 1 to each digit as we print (in "printsol").
/*
TASK: checker
LANG: C
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAXN 16
int n;
int nsol, nprinted;
char row[MAXN];
FILE *fout;
void
solution() {
int i;
for(i=0; i<n; i++) {
if(i != 0) fprintf(fout, " ");
fprintf(fout, "%d", row[i]+1);
}
fprintf(fout, "\n");
}
/* Keep track of whether there is a checker on each column, and diagonal. */
char col[MAXN]; /* (i, j) -> j */
char updiag[2*MAXN]; /* (i, j) -> i+j */
char downdiag[2*MAXN]; /* (i, j) -> i-j + N */
/*
* Calculate number of ways to place checkers
* on each row of the board starting at row i and going to row n.
*/
void
nway(i, lim) {
int j;
if(i == n) {
nsol++;
if (n > 6 && row[0] < n/2) nsol++;
if (nprinted++ < 3) solution();
return;
}
for(j=0; j<lim; j++){
if(!col[j] && !updiag[i+j] && !downdiag[i-j+MAXN]){
row[i] = j;
col[j]++;
updiag[i+j]++;
downdiag[i-j+MAXN]++;
nway(i+1,n);
col[j]--;
updiag[i+j]--;
downdiag[i-j+MAXN]--;
}
}
}
main(void) {
FILE *fin = fopen("checker.in", "r");
fout = fopen("checker.out", "w");
fscanf(fin, "%d", &n);
nway(0, n>6?(n+1)/2:n);
fprintf(fout, "%d\n", nsol);
exit (0);
}
Clever Michael Rybak's Solution
The Ukraine's Michael Rybak removed the 'this row is used' search (which obviously at the end of the recursion is a lot of wasted iterating) and replaced it with a list of valid rows to use (which presumably has but a single element at the end of the recursion). His program runs almost 4x faster then N==13.
Program Checker;
Var diagPLUS: Array[2..30] Of Boolean;
diagMINUS: Array[-15..15] Of Boolean;
sol: Array[1..15] Of ShortInt;
i,n,found: Longint;
stop: Boolean;
next,prev: Array[0..16] Of ShortInt;
sy: ShortInt;
Procere Search0(y:ShortInt);
Var x,i:ShortInt;
Begin
If stop Then Exit;
If y=n+1 Then Begin
Inc(found);
If found<4 Then Begin
For i:=1 To n-1 Do
Write(sol[i],' ');
Writeln(sol[n]);
End Else
stop:=True;
Exit;
End;
If sol[y]<>0 Then Begin
Search0(y+1);
Exit;
End;
x:=next[0];
While x<=n Do Begin
If Not ((diagPLUS[x+y]) Or (diagMINUS[x-y])) Then Begin
sol[y]:=x;
diagPLUS[x+y]:=True;
diagMINUS[x-y]:=True;
next[prev[x]]:=next[x];
prev[next[x]]:=prev[x];
Search0(y+1);
diagPLUS[x+y]:=False;
diagMINUS[x-y]:=False;
next[prev[x]]:=x; prev[next[x]]:=x;
End;
x:=next[x];
End;
sol[y]:=0;
End;
Procere Search;
Var x:ShortInt;
Begin
If sy=n+1 Then Begin
Inc(found);
Exit;
End;
If sol[sy]<>0 Then Begin
Inc(sy);
Search;
Dec(sy);
Exit;
End;
x:=next[0];
While x<=n Do Begin
If Not ((diagPLUS[x+sy]) Or (diagMINUS[x-sy])) Then Begin
sol[sy]:=x;
diagPLUS[x+sy]:=True;
diagMINUS[x-sy]:=True;
next[prev[x]]:=next[x];
prev[next[x]]:=prev[x];
Inc(sy);
Search;
Dec(sy);
diagPLUS[x+sy]:=False;
diagMINUS[x-sy]:=False;
next[prev[x]]:=x;
prev[next[x]]:=x;
End;
x:=next[x];
End;
sol[sy]:=0;
End;
Procere Search2(miny:Longint);
Var x,y,i:ShortInt;
curf:Longint;
Begin
x:=n Div 2+1;
For y:=miny To n Div 2 Do
If Not (diagPLUS[x+y] Or diagMINUS[x-y]) Then Begin
curf:=found;
sol[y]:=x;
diagPLUS[x+y]:=True;
diagMINUS[x-y]:=True;
next[prev[x]]:=next[x]; prev[next[x]]:=prev[x];
sy:=1;
Search;
If y>miny Then
found:=found+(found-curf);
sol[y]:=0;
diagPLUS[x+y]:=False;
diagMINUS[x-y]:=False;
next[prev[x]]:=x; prev[next[x]]:=x;
End;
End;
Procere Search1;
Var x,y,i:ShortInt;
Begin
y:=n Div 2+1;
For x:=1 To n Div 2 Do Begin
sol[y]:=x;
diagPLUS[x+y]:=True;
diagMINUS[x-y]:=True;
next[prev[x]]:=next[x]; prev[next[x]]:=prev[x];
Search2(x);
diagPLUS[x+y]:=False;
diagMINUS[x-y]:=False;
next[prev[x]]:=x; prev[next[x]]:=x;
End;
sol[y]:=0;
found:=found*4;
x:=n Div 2+1;
sol[y]:=x;
diagPLUS[x+y]:=True;
diagMINUS[x-y]:=True;
next[prev[x]]:=next[x]; prev[next[x]]:=prev[x];
sy:=1;
Search;
End;
Begin
Assign(Input,'checker.in'); Reset(Input);
Assign(Output,'checker.out'); Rewrite(Output);
Read(n);
found:=0;
FillChar(diagPLUS,SizeOf(diagPLUS),False);
FillChar(diagMINUS,SizeOf(diagMINUS),False);
FillChar(sol,SizeOf(sol),0);
For i:=0 To n+1 Do Begin
prev[i]:=i-1;
next[i]:=i+1;
End;
If n Mod 2=0 Then Begin
stop:=False;
Search0(1);
sy:=1;
found:=0;
Search;
End Else Begin
stop:=False;
Search0(1);
found:=0;
Search1;
End;
Writeln(found);
Close(Output);
End.
Clever Romanian Solution
Submitted by several from Romania, this solution uses bitmasks instead of a list to speed searching:
#include <stdio.h>
#include <stdlib.h>
#include <fstream.h>
#define MAX_BOARDSIZE 16
typedef unsigned long SOLUTIONTYPE;
#define MIN_BOARDSIZE 6
SOLUTIONTYPE g_numsolutions = 0;
void Nqueen(int board_size) {
int aQueenBitRes[MAX_BOARDSIZE]; /* results */
int aQueenBitCol[MAX_BOARDSIZE]; /* marks used columns */
int aQueenBitPosDiag[MAX_BOARDSIZE]; /* marks used "positive diagonals" */
int aQueenBitNegDiag[MAX_BOARDSIZE]; /* marks used "negative diagonals" */
int aStack[MAX_BOARDSIZE + 2]; /* a stack instead of recursion */
int *pnStack;
int numrows = 0; /* numrows rendant - could use stack */
unsigned int lsb; /* least significant bit */
unsigned int bitfield; /* set bits denote possible queen positions */
int i;
int odd = board_size & 1; /* 1 if board_size odd */
int board_m1 = board_size - 1; /* board size - 1 */
int mask = (1 << board_size) - 1; /* N bit mask of all 1's */
aStack[0] = -1; /* sentinel signifies end of stack */
for (i = 0; i < (1 + odd); ++i) {
bitfield = 0;
if (0 == i) {
int half = board_size>>1; /* divide by two */
bitfield = (1 << half) - 1;
pnStack = aStack + 1; /* stack pointer */
aQueenBitRes[0] = 0;
aQueenBitCol[0] = aQueenBitPosDiag[0] = aQueenBitNegDiag[0] = 0;
} else {
bitfield = 1 << (board_size >> 1);
numrows = 1; /* prob. already 0 */
aQueenBitRes[0] = bitfield;
aQueenBitCol[0] = aQueenBitPosDiag[0] = aQueenBitNegDiag[0] = 0;
aQueenBitCol[1] = bitfield;
aQueenBitNegDiag[1] = (bitfield >> 1);
aQueenBitPosDiag[1] = (bitfield << 1);
pnStack = aStack + 1; /* stack pointer */
*pnStack++ = 0; /* row done -- only 1 element & we've done it */
bitfield = (bitfield - 1) >> 1;
/* bitfield -1 is all 1's to the left of the single 1 */
}
for (;;) {
lsb = -((signed)bitfield) & bitfield;
/* this assumes a 2's complement architecture */
if (0 == bitfield) {
bitfield = *--pnStack; /* get prev. bitfield from stack */
if (pnStack == aStack) /* if sentinel hit.... */
break;
--numrows;
continue;
}
bitfield &= ~lsb; /* bit off -> don't try it again */
aQueenBitRes[numrows] = lsb; /* save the result */
if (numrows < board_m1) { /* more rows to process? */
int n = numrows++;
aQueenBitCol[numrows] = aQueenBitCol[n] | lsb;
aQueenBitNegDiag[numrows] = (aQueenBitNegDiag[n] | lsb) >> 1;
aQueenBitPosDiag[numrows] = (aQueenBitPosDiag[n] | lsb) << 1;
*pnStack++ = bitfield;
bitfield = mask & ~(aQueenBitCol[numrows] |
aQueenBitNegDiag[numrows] | aQueenBitPosDiag[numrows]);
continue;
} else {
++g_numsolutions;
bitfield = *--pnStack;
--numrows;
continue;
}
}
}
g_numsolutions *= 2;
}
int main(int argc, char** argv) {
ifstream f("checker.in");
ofstream g("checker.out");
long boardsize,s[20],ok,k,i,sol=0;
f>>boardsize;
Nqueen (boardsize);
k=1;
s[k]=0;
while (k>0) {
ok=0;
while(s[k]<boardsize && !ok) {
ok=1;
s[k]++;
for(i=1;i<k;i++)
if(s[i]==s[k] || abs(s[k]-s[i])==abs(k-i))
ok=0;
}
if(sol!=3)
if(!ok)
k--;
else
if(k==boardsize) {
for(i=1;i<boardsize;i++) {
for(int j=1;j<=boardsize;j++)
if(s[i]==j) g<<j<<" ";
}
for(i=1;i<=boardsize;i++)
if(s[boardsize]==i) g<<i;
g<<"\n";
sol++;
} else {
k++;
s[k]=0;
} else break;
}
g<<g_numsolutions<<"\n";
f.close();
g.close();
return 0;
}
這些程序你要先輸入一個數字,皇後數量,輸入8就行
Ⅳ 數據結構中有哪些基本演算法
數據結構中最基本的演算法有:查找、排序、快速排序,堆排序,歸並排序,,二分搜索演算法
等等。
1、用的最多也是最簡單的數據結構是線性表。
2、有前途的又難數據結構是圖 。
3、常用的80%演算法是排序和查找。
Ⅳ 應該先學演算法還是數據結構
個人愚見,數據結構是演算法的凝結品,因為各種數據常用或通用的數據結構能夠解決在實際應用中的一些問題,然而演算法就是解決問題的一套思路,當這套解決問題的思路固定之後,就會有相應成熟的數據結構產生,也就是雞和雞蛋那個先存在的問題,如果按照正常的思路,先學數據結構,然後再學演算法,不過一般在學數據結構的時候,肯定會有一些知名 的演算法會順帶地學到
Ⅵ 什麼是數據結構和演算法
數據結構,Data_Structure,其中D是數據元素的集合,R是該集合中所有元素之間的關系的有限集合。數據結構則是指相互之間存在一種或多種特定關系的數據元素的集合。通常情況下,精心選擇的數據結構可以帶來更高的運行或者存儲效率。數據結構往往同高效的檢索演算法和索引技術有關。
數據結構是計算機專業學生在大學期間都會學習的一門課程,但是由於課程偏理論,缺乏實際操作的學習體驗,而讓大家產生了一種「數據結構不重要,我只要學習了Java/C語言/Python同樣能敲代碼」的錯覺,但其實它是一門集技術性、理論性和實踐性於一體的課程。
演算法是某一系列運算步驟,它表達解決某一類計算問題的一般方法,對這類方法的任何一個輸入,它可以按步驟一步一步計算,最終產生一個輸出。
小碼哥的李明傑也說過所有的計算問題,都離不開要計算的對象或者要處理的信息,如何高效的把它們組織起來,就是數據結構關心的問題,所以演算法是離不開數據結構的,這就是數據與演算法。
Ⅶ 數據結構的結構演算法
演算法的設計取決於數據(邏輯)結構,而演算法的實現依賴於採用的存儲結構。數據的存儲結構實質上是它的邏輯結構在計算機存儲器中的實現,為了全面的反映一個數據的邏輯結構,它在存儲器中的映象包括兩方面內容,即數據元素之間的信息和數據元素之間的關系。不同數據結構有其相應的若干運算。數據的運算是在數據的邏輯結構上定義的操作演算法,如檢索、插入、刪除、更新和排序等。
數據的運算是數據結構的一個重要方面,討論任一種數據結構時都離不開對該結構上的數據運算及其實現演算法的討論。
數據結構不同於數據類型,也不同於數據對象,它不僅要描述數據類型的數據對象,而且要描述數據對象各元素之間的相互關系。
數據類型是一個值的集合和定義在這個值集上的一組操作的總稱。數據類型可分為兩類:原子類型、結構類型。一方面,在程序設計語言中,每一個數據都屬於某種數據類型。類型明顯或隱含地規定了數據的取值范圍、存儲方式以及允許進行的運算。可以認為,數據類型是在程序設計中已經實現了的數據結構。另一方面,在程序設計過程中,當需要引入某種新的數據結構時,總是藉助編程語言所提供的數據類型來描述數據的存儲結構。
計算機中表示數據的最小單位是二進制數的一位,叫做位。我們用一個由若干位組合起來形成的一個位串表示一個數據元素,通常稱這個位串為元素或結點。當數據元素由若干數據項組成時,位串中對應於各個數據項的子位串稱為數據域。元素或結點可看成是數據元素在計算機中的映象。
一個軟體系統框架應建立在數據之上,而不是建立在操作之上。一個含抽象數據類型的軟體模塊應包含定義、表示、實現三個部分。
對每一個數據結構而言,必定存在與它密切相關的一組操作。若操作的種類和數目不同,即使邏輯結構相同,數據結構能起的作用也不同。
不同的數據結構其操作集不同,但下列操作必不可缺:
1,結構的生成;
2.結構的銷毀;
3,在結構中查找滿足規定條件的數據元素;
4,在結構中插入新的數據元素;
5,刪除結構中已經存在的數據元素;
6,遍歷。
抽象數據類型:一個數學模型以及定義在該模型上的一組操作。抽象數據類型實際上就是對該數據結構的定義。因為它定義了一個數據的邏輯結構以及在此結構上的一組演算法。抽象數據類型可用以下三元組表示:(D,S,P)。D是數據對象,S是D上的關系集,P是對D的基本操作集。ADT的定義為:
ADT 抽象數據類型名:{數據對象:(數據元素集合),數據關系:(數據關系二元組結合),基本操作:(操作函數的羅列)}; ADT抽象數據類型名;抽象數據類型有兩個重要特性:
數據抽象
用ADT描述程序處理的實體時,強調的是其本質的特徵、其所能完成的功能以及它和外部用戶的介面(即外界使用它的方法)。
數據封裝
將實體的外部特性和其內部實現細節分離,並且對外部用戶隱藏其內部實現細節。
數據(Data)是信息的載體,它能夠被計算機識別、存儲和加工處理。它是計算機程序加工的原料,應用程序處理各種各樣的數據。計算機科學中,所謂數據就是計算機加工處理的對象,它可以是數值數據,也可以是非數值數據。數值數據是一些整數、實數或復數,主要用於工程計算、科學計算和商務處理等;非數值數據包括字元、文字、圖形、圖像、語音等。數據元素(Data Element)是數據的基本單位。在不同的條件下,數據元素又可稱為元素、結點、頂點、記錄等。例如,學生信息檢索系統中學生信息表中的一個記錄等,都被稱為一個數據元素。
有時,一個數據元素可由若干個數據項(Data Item)組成,例如,學籍管理系統中學生信息表的每一個數據元素就是一個學生記錄。它包括學生的學號、姓名、性別、籍貫、出生年月、成績等數據項。這些數據項可以分為兩種:一種叫做初等項,如學生的性別、籍貫等,這些數據項是在數據處理時不能再分割的最小單位;另一種叫做組合項,如學生的成績,它可以再劃分為數學、物理、化學等更小的項。通常,在解決實際應用問題時是把每個學生記錄當作一個基本單位進行訪問和處理的。
數據對象(Data Object)或數據元素類(Data Element Class)是具有相同性質的數據元素的集合。在某個具體問題中,數據元素都具有相同的性質(元素值不一定相等),屬於同一數據對象(數據元素類),數據元素是數據元素類的一個實例。例如,在交通咨詢系統的交通網中,所有的頂點是一個數據元素類,頂點A和頂點B各自代表一個城市,是該數據元素類中的兩個實例,其數據元素的值分別為A和B。 數據結構(Data Structure)是指互相之間存在著一種或多種關系的數據元素的集合。在任何問題中,數據元素之間都不會是孤立的,在它們之間都存在著這樣或那樣的關系,這種數據元素之間的關系稱為結構。
Ⅷ 程序=數據結構+演算法
數據結構:線性(Linear)、樹型(Tree)、圖(Graph)
演算法:排序(Sort)、查找(Search)、枚舉(Enum)等等...
演算法解決的是數據結構中的「增刪改查」,數據結構為的是讓計算機理解我們需要解決的問題是什麼東西。
一個問題,讓計算機理解它是什麼,然後我們通過『增刪改查』來達到解決問題的期望。
框架(framework)這個在2000年之前,其實計算機軟體開發當中並不怎麼使用這個詞,那個時候我們經常會說的是庫,SDK,API,例如:Win32 API,游戲開發中,我們也不叫框架,叫「引擎」,後來2000年後才逐步的開始使用這個名詞。框架實際上是利用設計模式,將某類型軟體開發中的常見問題,常用功能進行"封裝"(框架名詞與OOP關系很深)以達到更好的代碼復用率(少寫代碼),並且讓程序的設計工作以框架為主幹(骨骼)進行擴展和開發,也就是給你畫個框框,你的開發在這個框框中,框架決定你的開發模式、框架中提供的API決定了你編碼方式(介面),所謂的框架無非是利用了所謂的23種常見「軟體設計模式」中的一些模式來組織代碼,然後讓使用框架的人,陷入這個條條框框中,按照對方給你的API來進行軟體開發。
好處就是:標准化、簡單化
壞處就是:(依賴)框架的人,嚴格來說都是程序搬磚工而已
從開發成本的角度來看,框架可以縮短我們的開發周期,但從學習的角度來看,還不如深入的去了解數據結構與演算法以及設計模式,我們可以使用框架,但不要依賴框架。
數據結構:就是讓基本數據類型和復合數據類型以某種結構化的組織方式在計算機上進行數據的存儲,而演算法就是我們如何利用這些結構化的數據來解決實際問題方法。
計算就是一個IO設備,input -> (CPU、Memory、Storage) -> output
數據結構解決如何組織數據的輸入、數據的存儲、數據的輸出
演算法解決如何輸入、如何處理數據計算、如何輸出
數據結構與演算法是(心法),設計模式是(內功),編程語言是(招式)
沒有心法,內功等於0,招式就是假把式
有了心法,內功才有依靠,有了心法和內功,招式才能產生效果!
Ⅸ 數據結構 的演算法
FIFO 10次缺頁,分別是第1,2,3,4,8(1),10(2),11(3),12(4),13(6),14(1)頁
LRU 8次缺頁,分別是第1,2,3,4,8(3),12(4),13(6),14(1)頁
--------------------------------------
註:括弧內是缺頁時進程淘汰的頁號。因開始時進程中頁面為空,故前四次不淘汰頁面。
Ⅹ 數據結構和演算法
數據結構和演算法不是一個概念。
Data structure
and
Algorithm
書名字是兩種的話說裡面都有,一般的話這兩種是分不開的。如果只說數據結構的話書中比名字是兩種的少一部分內容,應該可以這樣理解。
單純的演算法有動態規劃,貪心,枚舉之類的,不需要比較麻煩的數據結構。
另外大部分的演算法都需要數據結構輔助,比如說搜索(隊列,棧或其它),單源最短路演算法(需要圖的結構,這部分應該屬於數據結構與演算法),還有些比較麻煩的。
數據結構中一般會存在演算法,比如二叉樹,平衡二叉樹,堆,棧,隊列……還有些比較麻煩的,線段樹,紅黑樹…………這之類的,裡面的數據結構的操作往往會涉及到一些精心設計的演算法來達到高效的目的。
二者不能是包含關系。