數(shù)據(jù)結(jié)構(gòu)導(dǎo)論算法總結(jié)

一瑰谜、線性表順序存儲(chǔ)

1、順序表的插入運(yùn)算*

順序表的插入運(yùn)算 InsertSeqlist (SeqList L,DataType x,int i)是指在順序表的第 i(1≤i≤ n+1)個(gè)元素之前贮庞,插入一個(gè)新元素 x。使長(zhǎng)度為 n 的線性表(a1辩涝,a2贸伐,…,ai-1怔揩, ai, ai+1脯丝,.…商膊,an)變?yōu)殚L(zhǎng)度為 n+1 的線性表(a1,a2宠进,…晕拆,ai-1,x, ai实幕,ai+1吝镣,.…,an)昆庇。 插入算法的基本步驟是:首先將結(jié)點(diǎn) ai~an 依次向后移動(dòng)一個(gè)元素的位置末贾,這樣空出第 i 個(gè)數(shù)據(jù)元素的位置;然后將 x 置入該空位整吆,最后表長(zhǎng)加 1

void InsertSeqlist(SeqList L,DataType x, int i) 
{
  if(L.length == Maxsize) exit("表已滿");
  if(i<1 || i>L.length + 1) exit("位置錯(cuò)"); //檢查插入位置是否合法
  for(j = L.length; j>=i;j--) //初始 i=L.length
    L.data[j] = L.data[j-1]; // 依次后移
  L.data[i-1] = x; //元素 x 置入到下標(biāo)為 i-1 的位置
  L.length++ //表長(zhǎng)度加 1
}

2拱撵、順序表的刪除*

刪除運(yùn)算 DeleteSeqlist(SeqList L,int i)是指將線性表的第 i(1≤i≤n)個(gè)數(shù)據(jù)元素刪去,使 長(zhǎng)度為 n 的線性表(a1表蝙,a2拴测,…,ai-1府蛇, ai集索,ai+1,.…汇跨,an)變?yōu)殚L(zhǎng)度為 n-1 的線性表(a1务荆, a2,…扰法,ai-1蛹含,ai+1,.…塞颁,an)浦箱。 刪除運(yùn)算的基本步驟是:①結(jié)點(diǎn) ai+1,…,an 依次向左移動(dòng)一個(gè)元素位置(從而覆蓋掉被刪 結(jié)點(diǎn) ai)祠锣;②表長(zhǎng)度減 1酷窥。此處無需考慮溢出,只判斷參數(shù) i 是否合法即可伴网。

void DeleteSeqlist(SeqList L, int i) 
{
  if(i<1 || i>L.length) exit("位置錯(cuò)")
  for(j=i;j < L.length; j++) // 第 i 個(gè)元素的下標(biāo)為 i-1
    L.data[j-1] = L.data[j] // 依次左移
  L.length-- //表長(zhǎng)度減 1
}

3蓬推、順序表定位運(yùn)算*

定位運(yùn)算 LocateSeqlist(SeqList L,DataType x)的功能是查找出線性表 L 中值等于 x 的結(jié) 點(diǎn)序號(hào)的最小值,當(dāng)找不到值為 x 的結(jié)點(diǎn)時(shí)澡腾,返回結(jié)果 0沸伏。下列算法從左往右掃描順序表 中的元素,考察元素的值是否等于 x

int LocateSeqlist(SeqList L, DataType x) 
{
  int i = 0;
  while((i < L.length) && (L.data[i] != x)) //在順序表中查找值為 x 的結(jié)點(diǎn)
    i++;
  if(i< L.length) return i+1; //若找到值為 x 的元素动分,返回元素的序號(hào)
  else return 0; // 未查找到值為 x 的元素毅糟,返回 0
}

二、單鏈表

1澜公、單鏈表的類型定義

typedef struct node 
{
  DataType data; // 數(shù)據(jù)域
  struct node * next; // 指針域

}Node,*LinkList

2姆另、單鏈表初始化*

空表由一個(gè)頭指針和一個(gè)頭結(jié)點(diǎn)組成

在算法中,變量 head 是鏈表的頭指針,它指向新創(chuàng)建的結(jié)點(diǎn)迹辐,即頭結(jié)點(diǎn)蝶防。一個(gè)空單鏈表 僅有一個(gè)頭結(jié)點(diǎn),它的指針域?yàn)?NULL明吩。

LinkList InitiateLinkList() 
{
  // 建立一個(gè)空的單鏈表
  LinkList head; //頭指針
  head=malloc(sizeof(Node)); //動(dòng)態(tài)構(gòu)建一結(jié)點(diǎn)间学,它是頭結(jié)點(diǎn)

  head->next = NULL;
  return head;
}

3、求表長(zhǎng)

在單鏈表存儲(chǔ)結(jié)構(gòu)中贺喝,線性表的表長(zhǎng)等于單鏈表中數(shù)據(jù)元素的結(jié)點(diǎn)個(gè)數(shù)菱鸥,即除了頭結(jié)點(diǎn)以外 的結(jié)點(diǎn)的個(gè)數(shù)。 設(shè)置一個(gè)工作指針 p躏鱼,初始時(shí)氮采,p 指向頭結(jié)點(diǎn),并設(shè)置一個(gè)計(jì)數(shù)器 cnt染苛,初值設(shè)置為 0鹊漠。然 后,讓工作指針 p 通過指針域逐個(gè)結(jié)點(diǎn)向尾結(jié)點(diǎn)移動(dòng)茶行,工作指針每向尾部移動(dòng)一個(gè)結(jié)點(diǎn)躯概,讓 計(jì)數(shù)器加 1。直到工作指針 p->next 為 NULL 時(shí)畔师,說明已經(jīng)走到了表的尾部娶靡,這時(shí)已完成 對(duì)所有結(jié)點(diǎn)的訪問,計(jì)數(shù)器 cut 的值即是表的長(zhǎng)度看锉。

int lengthLinklist (LinkList head)
{ Node *p;
  p=head; j=0;
  while( p->next != NULL )
  { p=p->next;
    j++;
  }
  return(j);
} 

4姿锭、讀表元素

通常給定一個(gè)序號(hào) i,查找線性表的第 i 個(gè)元素伯铣。在鏈表中呻此,任何相鄰的兩個(gè)結(jié)點(diǎn)通過一個(gè) 指針相連,一個(gè)結(jié)點(diǎn)的位置包含在直接前驅(qū)結(jié)點(diǎn)的 next 域中腔寡。所以焚鲜,必須從頭指針出 發(fā),一直往后移動(dòng)放前,直到第 i 個(gè)結(jié)點(diǎn)忿磅。

Node * GetlinkList(LinkList head, int i)
{
  Node * p;
  p=head->next; int c=1;
  while((c<1)&&(p!=NULL))
  {
    p=p->next;
    c++;
  }
  if(i==c) return(p);
  else return NULL;
}

4、定位*

線性表的定位運(yùn)算凭语,就是對(duì)給定表元素的值贝乎,找出這個(gè)元素的位置。在單鏈表的實(shí)現(xiàn)中叽粹,則 是給定一個(gè)結(jié)點(diǎn)的值,找出這個(gè)結(jié)點(diǎn)是單鏈表的第幾個(gè)結(jié)點(diǎn)。定位運(yùn)算又稱作按值查找虫几。 在定位運(yùn)算中锤灿,也需要從頭至尾訪問鏈表,直至找到需要的結(jié)點(diǎn)辆脸,返回其序號(hào)但校。若未找到, 返回 0啡氢。

int locateLinklist(LinkList head, DataType x)
{
  Node * p=head; // p是工作指針
  p=p->next; // 初始時(shí)p指向首結(jié)點(diǎn)
  int i=0; // i代表序號(hào)這里初值為0
  while(p!=NULL&&p->data!=x)
  {
    i++;
    p=p->next;
  }
  if(p!=NULL) return i+1;
  else return 0;
}

5状囱、插入*

單鏈表的插入運(yùn)算是將給定值為 x 的元素插入到鏈表 head 的第 i 個(gè)結(jié)點(diǎn)之前。

步驟:(1)先找到鏈表的第 i-1 個(gè)結(jié)點(diǎn) q倘是。(2)生成一個(gè)值為 x 的新結(jié)點(diǎn) p亭枷,(3) p 的指針域指 向 q 的直接后繼結(jié)點(diǎn)。

void InsertLinklist(LinkList head, DataType x,int i)
{
  //在表 head 的第 i 個(gè)數(shù)據(jù)元素結(jié)點(diǎn)之前插入一個(gè)以 x 為值的新結(jié)點(diǎn)
  Node *p,*q;
  if(i==1) q=head;
  else q=GetLinklist(head,i-1) //找第 i-1 個(gè)數(shù)據(jù)元素結(jié)點(diǎn)
  if(q==NULL)//第 i-1 個(gè)結(jié)點(diǎn)不存在

    exit("找不到插入的位置");
  else
  {
    p=malloc(sizeof(Node));p->data =x; //生成新結(jié)點(diǎn)
    p->next = q->next; //新結(jié)點(diǎn)鏈域指向*q 的后繼結(jié)點(diǎn)
    q->next = p; //修改*q 的鏈域
  }
}

注意:鏈接操作 p->next=q->next 和 q->next=p 兩條語句的執(zhí)行順序不能顛倒搀崭,否則結(jié) 點(diǎn)*q 的鏈域值(即指向原表第 i 個(gè)結(jié)點(diǎn)的指針)將丟失叨粘。

6、刪除

刪除運(yùn)算是給定一個(gè)值 i瘤睹,將鏈表中第 i 個(gè)結(jié)點(diǎn)從鏈表中移出升敲,并修改相關(guān)結(jié)點(diǎn)的指針域, 以維持剩余結(jié)點(diǎn)的鏈接關(guān)系轰传。

將 ai結(jié)點(diǎn)移出后驴党,需要修改該結(jié)點(diǎn)的直接前驅(qū)結(jié)點(diǎn)的 指針域,使其指向移出結(jié)點(diǎn) ai的直接后繼結(jié)點(diǎn)获茬。

void DeleteLinklist(LinkList head, int i)
{
  Node *q;
  if(i==1) q=head;
  else q=GetLinklist(head, i-1); //先找待刪結(jié)點(diǎn)的直接前驅(qū)
  if(q!==NULL&&q->next!=NULL) //若直接前驅(qū)存在且待刪結(jié)點(diǎn)存在
  {
    p=q->next; //p 指向待刪結(jié)點(diǎn)
    q->next = p->next; //移出待刪結(jié)點(diǎn)
    free(p); //釋放已移出結(jié)點(diǎn) p 的空間
  }
  else exit("找不到要?jiǎng)h除的結(jié)點(diǎn)");
}

三港庄、雙向循環(huán)鏈表

1、插入語句

在 p 所指結(jié)點(diǎn)的后面插入一個(gè)新結(jié)點(diǎn)*t锦茁,需要修改四個(gè)指針

(1) t->prior=p;
(2) t->next=p->next;
(3) p->next->prior=t;
(4) p->next=t

2攘轩、刪除

(1) p->prior->next=p->next; //p 前驅(qū)結(jié)點(diǎn)的后鏈指向 p 的后繼結(jié)點(diǎn)
(2) p->next->prior=p->prior; //p 后繼結(jié)點(diǎn)的前鏈指向 p 的前驅(qū)結(jié)點(diǎn)
(3) free(p); //釋放*p 的空間

四、棧

1码俩、順序棧類型定義

const int maxsize=6;
typedef struct seqstack {
    DataType data[maxsize];
    int top;
}SeqStk;

2度帮、順序棧初始化

int Initstack(SeqStk *stk)
{
  stk->top=0;
  return 1;
}

3、順序棧判斷椄宕妫空

int EmptyStack(SeqStk *stk)
{
  if(stk->top==0) return 1;
  else return 0;
}

4笨篷、順序棧進(jìn)棧

int Push(SeqStk *stk,DataType x)
{
  if(stk->top==maxsize-1) /*判是否上溢*/
  {
    error("棧滿"); return 0; /*上溢*/
  }
  else 
  {
    stk->top++;/*修改棧頂指針,指向新棧頂*/
    stk->data[stk->top] = x;/*元素x插入新棧頂中*/
    return 1;
  }
}

5瓣履、順序棧出棧

int Pop(SeqStk *stk)
{
  if(stk->top == 0)/*判是否下溢*/
  {
    error("椔食幔空"); return 0;/*下溢*/
  }
  else 
  {
    stk->top--; /*修改棧頂指針,指向新棧頂*/
    return 1;
  }
}

6袖迎、順序棧取棧頂元素

DataType GetTop(SeqStk *stk)
{
  if(stk->top==0)
  {
    return NULLData;
  }
  else
  {
    return stk->data[stk->top]
  }
}

7冕臭、鏈棧初始化

void InitStack(LkStk*LS) {
  LS=(LkStk*)malloc(sizeof(LkStk))
  LS->next = NULL
}

8腺晾、鏈棧判棧空

int EmptyStack(LkStk *LS) 
{
  if(LS->next == NULL) {
    return 1;
  } else {
    return 0;
  }
}

9辜贵、鏈棧進(jìn)棧

void Push(LkStk *LS,DataType x)
{
  LkStk*temp;
  temp = (LkStk*)malloc(sizeof(LkStk));
  temp->data=x;
  temp->next=LS->next;
  LS->next=temp;
}

10悯蝉、鏈棧出棧

int Pop(Lkstk*LS) 
{
  LsStk*temp;
  if(LS->next!== NULL)
  {
    temp=LS->next;
    LS->next=temp->next;
    free(p);
    return 1;
  }
  else return 0;
}

11、鏈棧取棧頂元素

DataType GetTop(LkStk*LS) 
{
  if(LS->next==NULL)
    return LS->next->data;
  else 
    return NULLData;
}

五托慨、隊(duì)列

1鼻由、循環(huán)對(duì)列入隊(duì)列

隊(duì)尾指針增1

sq.rear=(sq.rear+1)%maxsize

2、循環(huán)對(duì)列出隊(duì)列

sq.front=(sq.front+1)%maxsize

六厚棵、排序

1蕉世、冒泡排序

void BubbleSort(List R, int n) {
  int i, j, temp, endSort;
  for(i=1;i < n-1; i++) {
    endSort = 0;
    for(j=1;j < n-i;j++) {
      if(R[j].key > R[j+1].key) {
        temp = R[j].key;
        R[j].key = R[j+1].key;
        R[j+1].key = temp;
        endSort = 1;
      }
      if(endSort == 0) break;
    }
  }
}

2、直接插入排序

void StraighInsertSort(List R, int n) {
  int i, j;
  for(i=2;i<=n;i++) {
    R[0]=R[i];
    j=i-1;
    while(R[0].key<R[j].key) {
      R[j+1]=R[j];
      j--;
    }
    R[j+1]=R[0];
  }
}

持續(xù)更新中...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末婆硬,一起剝皮案震驚了整個(gè)濱河市狠轻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柿祈,老刑警劉巖哈误,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異躏嚎,居然都是意外死亡蜜自,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門卢佣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來重荠,“玉大人,你說我怎么就攤上這事虚茶「曷常” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵嘹叫,是天一觀的道長(zhǎng)婆殿。 經(jīng)常有香客問我,道長(zhǎng)罩扇,這世上最難降的妖魔是什么婆芦? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮喂饥,結(jié)果婚禮上消约,老公的妹妹穿的比我還像新娘。我一直安慰自己员帮,他們只是感情好或粮,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捞高,像睡著了一般氯材。 火紅的嫁衣襯著肌膚如雪渣锦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天浓体,我揣著相機(jī)與錄音泡挺,去河邊找鬼。 笑死命浴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贱除。 我是一名探鬼主播生闲,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼月幌!你這毒婦竟也來了碍讯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤扯躺,失蹤者是張志新(化名)和其女友劉穎捉兴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體录语,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡倍啥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了澎埠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虽缕。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蒲稳,靈堂內(nèi)的尸體忽然破棺而出氮趋,到底是詐尸還是另有隱情,我是刑警寧澤江耀,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布剩胁,位于F島的核電站,受9級(jí)特大地震影響祥国,放射性物質(zhì)發(fā)生泄漏昵观。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一系宫、第九天 我趴在偏房一處隱蔽的房頂上張望索昂。 院中可真熱鬧,春花似錦扩借、人聲如沸椒惨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽康谆。三九已至领斥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沃暗,已是汗流浹背月洛。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留孽锥,地道東北人嚼黔。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像惜辑,于是被迫代替她去往敵國(guó)和親唬涧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容