1. 程式人生 > >有關帶頭結點的單鏈表的基本操作

有關帶頭結點的單鏈表的基本操作

帶頭結點的連結串列:建立(頭插法)、輸出、查詢、插入(差後面)、刪除

  • 關於建立:
    頭指標的建立提供了便利,不必考慮建立第一個結點的特殊情況
    頭插法較尾插法在連結串列建立中更為標準(霧),可以不用定義指標pta指向尾結點;
    注意頭結點的定義在create函式中哦

  • 關於遍歷(輸出)
    先將p=p->next以跳過頭結點從第一個結點開始輸出

  • 關於查詢
    該部分有無頭指標差別不大(甚至可以根本沒有差別)

  • 關於插入
    普遍的插入規則是插入到指定結點的後一個(好像也有前一個的吧?),那麼要把插入的變為第一個結點就要插在頭指標後面,可以把頭指標的資訊域賦值,這樣就可以查詢啦。不必考慮第一個結點的特殊情況

  • 關於刪除
    不必考慮第一個結點的特殊情況,還是挺簡單的吧

#include<stdio.h>
struct student//定義結構體
{
 int num;//資訊域
 float score;
 struct student *next;//指標域
};
struct student * create() //建立連結串列 返回值為結構體指標 頭插法
{
 int num;
 float score;
 struct student *ph, *pte;//無需建立尾節點對應指標,若是尾插法則需要
 ph = (struct student *)malloc(sizeof(struct student));//注意也要為頭結點申請空間
 ph->next = NULL;///頭結點的指標域為初始化NULL
 ph->num = -1;
 scanf("%d%f", &num, &score);
 while (score >= 0)//無需單獨考慮第一個結點的情況
 {
  pte = (struct student *)malloc(sizeof(struct student));
  pte->num = num;pte->score = score;
  pte->next =ph->next;//若為第一個結點pte->next指向NULL,若不是則指向原第一個結點//接後面
  ph->next = pte;//接前面
  scanf("%d%f", &num, &score);
 }
 return ph;
}
void list(struct student *p)//輸出連結串列 無返回值 形參為頭指標
{
 p = p->next;//跳過頭結點
 while (p)
 {
  printf("%d      %f\n", p->num, p->score);
  p =p ->next;
 }
}
struct student * search(struct student *p, float s)//結點查詢,按分數找學號,返回找到的結點的地址 ,並輸出p->name
{
 while (p)
 {
  if (p->score == s)//找到了就跳出迴圈並返回此時的p
   break;
  p = p->next;
 }
 return p;//如果沒找到,則p最後為NULL,迴圈結束
}
struct student * ins(struct student *p, int ns, int n, float s)//插入結點在ns之後
{
 struct student *pt;
 struct student *ph = p;
 pt = (struct student *)malloc(sizeof(struct student));
 pt->num = n;pt->score = s;pt->next = NULL;
 while (p)//找到結點ns並使p指向它
 {
  if (p->num == ns)
   break;
  p = p->next;
 }//可插在連結串列的任何位置
  pt->next = p->next;//接後面
  p->next = pt;//接前面
 return ph;
}
struct student * del(struct student *p, int n)//刪除結點 返回值為結構體指標即修改過的頭指標 傳入原頭指標和name
{
 struct student *pre = p;//定義pre臨時,記錄要刪除結點的地址
 struct student *ph = p;//定義ph用於返回
 while (p)//遍歷連結串列 
 {
  if (p->num == n)//找到啦,跳出迴圈,p指向要刪除的結點
   break;
  pre = p;//pre就指向了要刪除的那個結點之前
  p = p->next;//p就指向下一個
 }
 pre->next = p->next;//找到之後呢,讓這個結點之前pre的next指向改結點的next
 free(p);//然後釋放這個結點
 return ph;
}
int main()
{
 struct student *ph,*pt;
 printf("建立:輸入score<0以結束連結串列建立\n");
 ph = create();
 list(ph);
 //
 printf("查詢:輸入score以查詢對應num\n");
 float s1;
 scanf("%f", &s1);
 pt = search(ph, s1);//
 if (pt)//找到了,此時pt非空
  printf("%d\n", pt->num);//輸出其指向的num
 else
  printf("NONE\n");
 //
 int ns, n;
 float s;
 printf("插入:輸入num=-1以將結點設定為第一個\n");
 scanf("%d%d%f", &ns, &n, &s);
 ph = ins(ph, ns, n, s);
 list(ph);
 //
 printf("刪除:輸入要刪除的num");
 int n1;
 scanf("%d", &n1);
 ph = del(ph, n1);//傳入頭指標和要刪除的num,將更改過的頭指標傳給ph
 list(ph);
 //
 getchar();getchar();
 return 0;
}