1. 程式人生 > 其它 >[ACM]數列分塊,ST表

[ACM]數列分塊,ST表

連結串列

如下圖所示即為普通的單鏈表結構:

一、概念

  N個節點(node)離散分配、彼此通過指標相連、每個節點只有一個前驅節點和一個後驅節點,首節點沒有前驅節點,尾節點沒有後續節點

  專業術語:

  • 首節點:存放第一個有效資料的節點
  • 尾節點:存放最後一個有效資料的節點
  • 頭節點:首節點之前的那個節點,頭節點並不存放有效資料, 目的主要是為了方便對連結串列的操作
  • 頭指標:指向頭節點的指標變數
  • 尾指標:指向尾節點的指標變數

  優點:不受個數限制

二、連結串列的分類

  • 按指標域分:  

  單鏈表:每個節點只有一個指標域

  雙鏈表:每個節點有兩個指標域

  • 按迴圈分:

  迴圈連結串列:能通過任何一個節點找到其它所有節點

  非迴圈連結串列:不能通過任何一個節點找到其它所有節點

三、連結串列引數

  當使用一個函式對連結串列進行操作的時候,只需要傳遞頭指標給函式即可。

四、連結串列基本操作

  • 初始化(建立連結串列):宣告一個結構體型別,內涵資料域和指標域兩個成員。
  • 遍歷:根據最後一個節點指標域是否為NULL判斷
  • 判斷空/滿
  • 求長度
  • 插入元素:

  • 刪除元素:

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

typedef struct Node
{
    int data;//資料域
    struct
Node *pNext;//指標域 }NODE,*PNODE; PNODE create_list(); int is_empty(PNODE pHead); int length_list(PNODE); int insert_list(PNODE,int,int); int delete_list(PNODE,int,int*); void sort_list(PNODE); void traverse_list(PNODE pHead); int main() { int len,val; PNODE pHead = NULL;//頭指標,重要成分之一 pHead=create_list();//
建立一個非迴圈單鏈表 traverse_list(pHead);//遍歷輸出連結串列 len=length_list(pHead); printf("長度為%d\n",len); sort_list(pHead); traverse_list(pHead); insert_list(pHead,4,99); traverse_list(pHead); delete_list(pHead,4,&val); traverse_list(pHead); printf("刪除的元素是%d\n",val); return 0; } PNODE create_list() { int len; int i,val;//val是中間儲存用的 PNODE pHead,pTail,pNew;//頭指標,尾指標總是指向尾節點的 pHead=(PNODE)malloc(sizeof(NODE));//為頭指標分配記憶體 if(pHead==NULL) { printf("記憶體分配失敗,程式結束"); exit(-1); } pTail=pHead; pTail->pNext=NULL;//確保len是0的時候,結尾是空指標 printf("請輸入連結串列節點個數 len=\n"); scanf("%d",&len); for(i=0;i<len;i++) { printf("請輸入儲存的第%d個數據:",i+1); scanf("%d",&val); pNew=(PNODE)malloc(sizeof(NODE));////不用一次性分配太多記憶體 if(pNew==NULL) { printf("記憶體分配失敗,程式結束"); exit(-1); } pNew->data=val;//1優先處理好新節點的data和pNext pNew->pNext=NULL; pTail->pNext=pNew;//2連線兩個節點 pTail=pNew;//3永遠指向尾指標 } return pHead; } void traverse_list(PNODE pHead) { PNODE p=pHead->pNext; while(p!=NULL)//遍歷直至尾節點的指標域為NULL,注意是p不是p->pNext { printf("%d ",p->data); p=p->pNext; } printf("\n"); return; } int is_empty(PNODE pHead) { if(pHead->pNext==NULL) return 1; return 0; } int length_list(PNODE pHead) { PNODE p=pHead->pNext; int len=0; while(p!=NULL) { len++; p=p->pNext; } return len; } void sort_list(PNODE pHead) { int i,j,t; int len=length_list(pHead); PNODE p,q; for(i=0,p=pHead->pNext;i<len-1;i++,p=p->pNext) { for(j=i+1,q=p->pNext;j<len;j++,q=q->pNext) { if(p->data>q->data) { t=p->data; p->data=q->data; q->data=t; } } } return; } int insert_list(PNODE pHead,int pos,int val) { int i=0; PNODE p,pNew; p=pHead; while(p!=NULL && i<pos-1) { p=p->pNext; i++; } if(p==NULL || i>pos-1)//後者是用來防止pos<1的情況,而前者是防止pos大於節點個數 return 0; pNew=(PNODE)malloc(sizeof(NODE)); if(pNew==NULL) exit(-1); pNew->data=val; pNew->pNext=p->pNext; p->pNext=pNew; return 1; } int delete_list(PNODE pHead,int pos,int *val) { int i=0; PNODE p,q; p=pHead; while(p!=NULL && i<pos-1) { p=p->pNext; i++; } if(i>pos-1 || p==NULL) return 0; q=p->pNext; *val=q->data; p->pNext=p->pNext->pNext; free(q);//注意釋放記憶體 q=NULL;//然後零中間的指標置空 return 1; }