建立單線性鏈表的不同表示方法和操作,建立線性表示

來源:互聯網
上載者:User

建立單線性鏈表的不同表示方法和操作,建立線性表示

          建立單線性鏈表,常見的有頭插法、尾插法建立線性鏈表,常見的操作有:建立鏈表、尋找、刪除、增加元素、求逆鏈等操作。

這裡首先用頭插法建立鏈表:

//頭指標唯一確定一個單鏈表

  #define MaxSize 15    typedef int elem_type ;   typedef struct linklist   {     elem_type data;     struct linklist *next;   } Linklist;     //頭插入法建立鏈表:每次將頭結點的指標賦值給新結點,然後將新節點賦值給頭結點指標      Linklist *CreateList ()      {        Linklist *head,*p;        head =(Linklist *)malloc(sizeof(Linklist));head->next=NULL;       // p =(Linklist *)malloc(sizeof(Linklist));        int i;cout<<"隨機產生一個數字:"<<endl;        for(i=0;i<MaxSize;i++)        {          int data;          data =rand()%100;  p =(Linklist *)malloc(sizeof(Linklist));  cout<<"第"<<i<<"個數是"<<data<<endl;          p->data =data;          p->next=head->next;          head->next=p;        }       return head;      }
      //利用頭插法建立的鏈表有什麼特點呢?

  這裡可以寫個尋找函數來說明:

     定義一個尋找函數:

//尋找(取出第i個數的值)  elem_type Get_Elem(Linklist *L, int i)      {   int j;   Linklist *p;   p=L->next;   if((i>MaxSize) && (i< 0))     cout<<"輸入有效i值";   for(j=0;j<i-1;j++)       {   p=p->next;     //flag->next++;  //鏈表不是矩陣,指標自加1不是指向下一個結點,那是矩陣裡可以這樣。     }   return p->data;}
         編譯一下:結果如下

//主函數如下:

int main(){  Linklist *Q;  Q=CreateList();  int i;  cout<<"輸入想要尋找的元素號i=";  cin>>i;  int getNum = Get_Elem( Q , i);  cout<<"第"<<i<<"個元素是"<<getNum<<endl;  //Insert_Elem(Q, 3,5);  while(1);  return 0;}
    
             根據運行結果可知道:對於頭插法,輸入的結點次序和產生的鏈表次序相反。

       還有可以有:刪除元素和增添元素的函數體:

//刪除鏈表中的某個結點void Delete_Linklist(Linklist *L,elem_type i)   {  Linklist *p,*q;  p=L->next;  int j=0;  if(i<0 && i>MaxSize )  cout<<"j輸入有效i值";  else  {  while((p->next != NULL)&&(j<i-1))  {  p=p->next;  //尋找第i個結點    ++j;  }   q=p->next;   p->next=q->next;   free(q);  }  }//添加結點(在第i個節點處添加一個值) void Insert_Elem(Linklist *L, int i, elem_type Number)      {   int j;   Linklist *p,*q;   p=L->next;   if((i>MaxSize) && (i< 0))     cout<<"輸入有效i值";   for(j=0;j<i-1;j++)       {   p=p->next;     //flag->next++;  //鏈表不是矩陣,指標自加1不是指向下一個結點,那是矩陣裡可以這樣。     }   if(i==j+1)     {q=(Linklist *)malloc(sizeof(Linklist));     q->data=Number;     q->next=p->next;     p->next=q;     }  //  return p;    }

       

      問題分析:為什麼頭插法的資料元素順序和鏈表中結點順序相反?

迴圈第一次時:

          p->data =data;          //資料元素第一次賦值          p->next=head->next;    //迴圈賦值,第一次將NULL賦給p->next,          head->next=p;         //第一次賦值後的p賦給head->next;

迴圈第二次時:

          p->data =data;         //資料元素第二次賦值          p->next=head->next;    //迴圈賦值,第二次將 (第一次賦值後的<span style="font-family: Arial, Helvetica, sans-serif;">head->next</span><span style="font-family: Arial, Helvetica, sans-serif;">)賦給p->next,</span>          head->next=p;         //第二次賦值後的p賦給head->next;

       所以新賦值進來的結點更靠近head->next.





      


建立單向動態鏈表,並對它進行插入、刪除與輸入等操作,包括以下任務:

#include<stdio.h>
#define LEN sizeof(struct number)
struct number /*定義編號和數字*/
int name;
int num;
struct number * next;
};

struct number * create() /*建立鏈表函數*/
{
struct number * head,* new,* tail,* p;
int count=0;
while(1)
{
new=(struct number *)malloc(LEN);
printf("input Name and Number\n");
scanf("%d %d",&new->name,new->num); /*使用者輸入編號和數字*/
if(new->name==0)
{
free(new);
break;
}
else if(count==0)
{
head=new;
tail=new;
}
else
{
tail->next=new;
tail=new;
}
count++;
}
tail->next=NULL;
return(head);
}

struct number * delist(struct number *head,int name) /*刪除數位函數*/
{
struct number * p0,* p1;
p1=head;
if(head==NULL)
{
printf("\nempty list!\n");
}
else
if(p1->name==name) /*找到相同編號*/
head=p1->next;
else
{
while(p1->name!=name&&p1->next!=NULL) /*逐一排查*/
{
p0=p1;
p1=p1->next;
}
if(p1->name==name)
{
p0->next=p1->next;
printf("The node is deleted\n");
}
else
printf("The node can not been foud!\n");
}
return head;
}

struct number * insert(struct number * head,struct number * new)
{ ......餘下全文>>
 
單鏈表的操作

1.單鏈表的類型定義
typedef struct Node *PNode; /* 結點指標類型 */
struct Node /* 單鏈表結點結構 */
{
DataType data; /* 範圍 */
struct Node *next; /* 指標域 */
};
為提高可讀性,可定義單鏈表類型如下:
typedef struct Node *LinkList;
LinkList list; /* 定義一單鏈表list */
PNode p; /* 定義一單鏈表結點指標
則指標p所指結點的兩個域表示為:
值 域: p->data
指標域: p->next
註:設定表頭結點的目的是統一空鏈表與非空鏈表的操作,簡化鏈表操作的實現。帶頭結點的空鏈表表示為:list->next==NULL;而不帶頭結點的空鏈表只能表示為list==NULL;
單鏈表的常用演算法(帶頭結點)
演算法 1 建立空單鏈表LinkList createNullist_link( void )
分析:申請一表頭結點的儲存空間,並將該結點指標域置空
LinkList CreateNullist_link(void)
{
LinkList list=(LinkList)malloc(sizeof(struct Node));
               //申請表頭結點儲存空間
if( list != NULL) list->next=NULL;
else printf(“Out of space!\n”); //建立失敗
return(list);
}
註:演算法中malloc為記憶體申請函數,需標頭檔stdlib.h支援。
演算法 2 單鏈表的插入 int insert_link( LinkList list, PNode p, DataType x )
插入結點演算法:
   首先產生待插入結點q,將其範圍置為x,然後通過修正指標將結點q插入到結點p之後。
插入實現:
q->data=x; //產生待插入結點
q->next=p->next;
p->next=q;
演算法 3 單鏈表結點的刪除 int delete_link(LinkList list, DataType x )
刪除結點演算法:  首先在list 帶有頭結點的單鏈表中找到第一個值為x的結點q,並記錄其前驅結點的位置p,然後通過指標修正刪除結點q。
刪除實現:
q=p->next;
p->next=q->next;
free(q);

...餘下全文>>

 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.