實戰資料結構(1)_單連結串列的操作

YunShell發表於2013-08-21

      單連結串列的操作是資料結構開始的入門,包括建立,插入,刪除,銷燬等操作。下面是一個簡單的例子,用於總結複習。

1.建立一個帶頭結點的連結串列,其實就是一個頭節點,然後其後繼元素next為NULL.所有的節點元素都是附加在其後的。

2.插入連結串列,主要傳過來頭節點和要插入的位置,插入的時候,也是很簡單,無非是需要兩個指標,一個前驅指標pre,一個當前插入位置的指標cur。 在堆上開闢新的節點後,其節點指標為p;所以插入的順序為:pre->next=p;p->next=cur;這樣就完成了一個節點的插入,同時在插入的時候,還要考慮位置的合法性,以及是不是最後一個位置插入,如果是最後一個位置插入,就只需要,cur和p.直接,cur->next=p;

3.刪除節點操作,也是和上面類似,需要 pre.cur.pre->next=cur->next;free(cur);OK

4.查詢元素:

<1>按位置查詢,當然是先找到位置,因為單連結串列的位置都是需要遍歷的,先用迴圈找到要查詢的位置指標,然後列印出資料元素。

<2>按值查詢,就是根據值來匹配,比如查詢序號為某個數的學生資料,也是要遍歷,然後列印5.銷燬連結串列,因為這種動態開闢的連結串列,都是在堆上的開闢記憶體,在不用的時候,必須釋放掉,銷燬連結串列也是,依次free(p),用迴圈。總結: 在對連結串列操作的過程中,c的用法還是有點問題,還是不能一次性編碼正確,這裡犯了scanf(“%S,%S”)的錯誤,用scanf來進行接受兩個字串的操作,這裡的","將也會被認為是第一個字串的字元,並沒有起到隔離兩個字串的作用。而且對單個字元操作的時候,要注意,回車也是一個字元,將被接受進入記憶體,只是在記憶體中。所以在進行接受兩個字元的時候,用scanf(“%S %S”)中間用空格隔開,這個問題先記著在去看。

#include <stdio.h>  
#include <stdlib.h>  
  
typedef struct node  
{     
    int num;  
    char name[10];  
    char score[10];  
    struct node *next;  
}stuinfo;  
static int length;  
  
void CreateList(stuinfo *h,int x);  
void printfSingleList(stuinfo *h);  
void InsertSingleList(stuinfo *h,int pos);  
void DeleteSingleList(stuinfo *head,int num);  
void findelement_bypos(stuinfo *head,int pos);  
void findelement_bynum(stuinfo *head,int num);  
int main()  
{     
    static stuinfo *head;  
    head=(stuinfo *)malloc(sizeof(stuinfo)); //開闢一個頭結點  
    if(NULL==head)  
    {  
        printf("malloc申請失敗");  
        exit(-1);  
    }  
    head->next=NULL;  
    while(1)  
    {  
        printf("1---建立連結串列\n");  
        printf("2---插入連結串列\n");  
        printf("3---刪除連結串列\n");  
        printf("4---列印當前連結串列元素\n");  
        printf("5---按位置查詢\n");  
        printf("6---按學號查詢\n");  
        printf("7---退出\n");  
        int choice,num;  
        printf("請輸入選擇:\n");  
        scanf("%d",&choice);  
        switch(choice)  
        {  
            case 1:  
                {     
                    printf("請輸入新建元素個數\n");  
                    scanf("%d",&num);  
                    length=num;  
                    CreateList(head,num);  
                    break;  
                }  
            case 2:  
                {   printf("請輸入插入位置\n");  
                    scanf("%d",&num);  
                    InsertSingleList(head,num);  
                    break;  
                }  
            case 3:  
                {   printf("請輸入刪除的位置\n");  
                    scanf("%d",&num);  
                    DeleteSingleList(head,num);  
                    break;  
                }  
            case 4:  
                {     
                    printfSingleList(head);  
                    break;  
                }  
            case 5:  
                {   printf("請輸入查詢的位置\n");  
                    scanf("%d",&num);  
                    findelement_bypos(head,num);  
                    break;  
                }  
            case 6:  
                {  
                    printf("請輸入查詢的學號\n");  
                    scanf("%d",&num);  
                    findelement_bynum(head,num);  
                    break;  
                }  
            case 7:  
                {  
                    return 1;  
                }  
            default:  
                break;  
        }     
    }  
        return 1;  
}  
  
  
void CreateList(stuinfo *h,int x)  
{  
    stuinfo *head=h;   
    stuinfo *pre=head;  
    stuinfo *newnode;  
    for(int i=1;i<=x;i++)  
    {     
        if(NULL==(newnode=(stuinfo *)malloc(sizeof(stuinfo))))//開闢一個新節點  
        {  
            printf("malloc申請失敗");  
            return ;  
        }  
    //  newnode->next=NULL;  //在每個節點都分配NULL  
        printf("請輸入第%d個學生資訊\n",i);  
        scanf("%d %s %s",&(newnode->num),newnode->name,newnode->score);  
        pre->next=newnode;  
        pre=newnode;  
    }  
    pre->next=NULL;  
    return ;  
}  
  
void printfSingleList(stuinfo *h)  
{  
    stuinfo *p=h->next;  
    if(p==NULL)  
    {  
        printf("當前連結串列為空\n");  
        exit(-1);  
    }  
    while(p!=NULL)  
    {  
        printf("學號%d 姓名 %s 分數 %s\n",p->num,p->name,p->score);  
        p=p->next;  
    }  
    return ;  
}  
  
void InsertSingleList(stuinfo *h,int pos)  
{     
      
    if(pos<1||pos>length+1)	  //位置時候無效  
    {   printf("插入位置error\n");  
        return ;  
    }  
    else   //位置有效
    {     
        stuinfo *pre=h,*cur;  
        if(NULL==(cur=(stuinfo *)malloc(sizeof(stuinfo))))//開闢一個新節點  
        {  
            printf("malloc申請失敗");  
            return ;  
        }  
        printf("請輸入插入資訊\n");  
        scanf("%d %s %s",&(cur->num),cur->name,cur->score);  
           
        for(int i=1;i<pos;i++)  //查詢前驅節點
			 pre=pre->next;

		cur->next=pre->next; //
		pre->next=cur;  
		length++; //更新長度  
		return ;  
    }  
}  
  
void DeleteSingleList(stuinfo *head,int pos)  
{  
    if(pos<1||pos>length)  
    {  
        printf("刪除位置錯誤\n");  
        return;  
    }  
    else  
    {  
        stuinfo *pre=head;
        for(int i=1;i<pos;i++) //查詢要刪除的前驅節點
				pre=pre->next;
		stuinfo *p=pre->next;
        pre->next=p->next;  
        free(p);  
        length--;  
        return ;  
    }  
}     
 /************************************************************************/
 /* 總結:
插入和刪除其實都是在找前驅指標pre.
1.插入的時候,先更新新節點的Next域,然後在更新pre的next域
2.刪除時候,要記得p=pre->next不然會出錯。
   不能:	pre->next=pre->next->next;
			free(pre->next)
                                                                  */
 /************************************************************************/
void findelement_bypos(stuinfo *head,int pos)  
{  
    if(pos<1||pos>length)  
    {  
        printf("查詢位置error\n");  
        return ;  
    }  
    else  
    {  
        stuinfo *p=head;  
        for(int i=0;i<pos;i++)  
            p=p->next;  
        printf("%d %s %s\n",p->num,p->name,p->score);  
    }  
    return  ;  
}  
  
  
void findelement_bynum(stuinfo *head,int num)  
{  
    stuinfo *p=head->next;  
    while(p->num!=num)  
        p=p->next;  
    if(NULL==p)  
    {  
        printf("查詢不到\n");  
        return ;  
    }  
    else {  
        printf("學號%d 姓名 %s 分數 %s\n",p->num,p->name,p->score);  
    }  
    return ;  
}  

相關文章