實驗目的及要求:
目標是使學生學會分析數據對象的特點,掌握數據組織的方法和在計算機中的存儲方式,能夠對具體問題中所涉及的數據選擇合適的邏輯結構、存儲結構,進而在此基礎上,對各種具體操作設計高效的算法,培養良好的程序設計技能。
實驗設備環境:
1.微型計算機
2.DEV C++(或其他編譯軟件)
實驗步驟:
任務一:
編寫算法實現帶頭結點單鏈表的就地逆置,即利用原帶頭結點單鏈表的結點空間把元素序列 a0,al,……,an-i 逆置為 an-1,……,al, a0?
[程序參數設計] 定義了一個帶頭結點的單鏈表結構體,并提供了初始化、尾部插入、打印、就地逆置和釋放鏈表的函數。在主函數中,首先初始化鏈表,然后添加一些元素,打印原始鏈表,執行就地逆置,最后打印逆置后的鏈表并釋放鏈表的空間。
代碼如下:
#include<stdio.h>
#include<malloc.h>
typedef int DataType;
#include "LinList.h"
int main(void){SLNode*head,*p,*q,*temp;int i,j,x;ListInitiate(&head);for(i=0;i<10;i++)ListInsert(head,i,i+1);printf("原來鏈表:"); for(i=0;i<ListLength(head);i++){ListGet(head,i,&x);printf("%d ",x);}printf("\n");for(i=1;i<=ListLength(head)-1;i++){temp=head;p=head->next;q=p->next;for(j=1;j<=ListLength(head)-i&&q!=NULL;j++){temp->next=q;temp=q;p->next=q->next;q->next=p;q=p->next;}} printf("當前鏈表:");for(i=0;i<ListLength(head);i++){ListGet(head,i,&x);printf("%d ",x);}Destroy(&head);
}
頭文件:typedef struct Node{DataType data;struct Node *next;
}SLNode;
void ListInitiate(SLNode**head){*head=(SLNode *)malloc(sizeof(SLNode));(*head)->next=NULL;
}
int ListLength(SLNode *head){SLNode *p=head;int size=0;while(p->next!=NULL){p=p->next;size++;}return size;
}
int ListInsert(SLNode *head,int i,DataType x){SLNode *p,*q;int j;p=head;j=-1;while(p->next!=NULL&&j<i-1){p=p->next;j++;}if(j!=i-1){printf("插入元素位置參數錯!");return 0;}q=(SLNode *)malloc(sizeof(SLNode));q->data=x;q->next=p->next;p->next=q;return 1;
}
int ListDelete(SLNode *head,int i,DataType *x){SLNode *p,*s;int j;p=head;j=-1;while(p->next!=NULL&&p->next->next!=NULL&&j<i-1){p=p->next;j++;}if(j!=i-1){printf("刪除元素位置參數錯!");return 0;}s=p->next;*x=s->data;p->next=p->next->next;free(s);return 1;
}
int ListGet(SLNode *head,int i,DataType *x){SLNode *p;int j;p=head;j=-1;while(p->next!=NULL&&j<i){p=p->next;j++;}if(j!=i){printf("取出元素位置參數錯!");return 0;}*x=p->data;return 1;
}
void Destroy(SLNode **head){SLNode *p,*p1;p=*head;while(p!=NULL){p1=p;p=p->next;free(p1);}*head=NULL;
}
任務二:
設計循環單鏈表。要求:?
(1)循環單鏈表的操作,包括初始化,求元素個數,插入、刪除、取元素。?
(2) 設計一個測試主函數驗證所設計循環單鏈表的正確性。
[程序參數分析] 定義 Node 結構體來表示循環單鏈表的結點,頭結點的 next 指針指向鏈表的首結點,而最后一個結點的 next 指針指向頭結點,形成循環。程序提供了初始化、求元素個數、插入、刪除、取元素、打印、釋放鏈表空間等函數。在主函數中,我們演示了插入、刪除、獲取元素、打印鏈表長度和釋放鏈表的操作。
代碼如下:
#include<stdio.h>
#include<malloc.h>
typedef int DataType;
#include"LinListO.h"
int main(void){SLNode *head,*p;int i,x;ListInitiate(&head);for(i=0;i<10;i++){ListInsert(head,i,i+1);}//ListDelete(head,4,&x);printf("鏈表中的元素:");for(i=0;i<ListLength(head);i++){ListGet(head,i,&x);printf("%d ",x);}//printf("\n%d ",head->next->data);//printf("\n%d ",head->next->next->next->next->next->next->data);int j=-1;p=head;while(p->next!=head){p=p->next;j++;}ListGet(head,j,&x);printf("\n");printf("%d",x);Destroy(&head);
}
頭文件:
typedef struct Node{DataType data;struct Node *next;
}SLNode;
void ListInitiate(SLNode**head){*head=(SLNode *)malloc(sizeof(SLNode));(*head)->next=*head;
}
int ListLength(SLNode *head){SLNode *p=head;int size=0;while(p->next!=head){p=p->next;size++;}return size;
}
int ListInsert(SLNode *head,int i,DataType x){SLNode *p,*q;int j;p=head;j=-1;while(p->next!=head&&j<i-1){p=p->next;j++;}if(j!=i-1){printf("插入元素位置參數錯!");return 0;}q=(SLNode *)malloc(sizeof(SLNode));q->data=x;q->next=p->next;p->next=q;return 1;
}
int ListDelete(SLNode *head,int i,DataType *x){SLNode *p,*s;int j;p=head;j=-1;while(p->next!=head&&p->next->next!=head&&j<i-1){p=p->next;j++;}if(j!=i-1){printf("刪除元素位置參數錯!");return 0;}s=p->next;*x=s->data;p->next=p->next->next;free(s);return 1;
}
int ListGet(SLNode *head,int i,DataType *x){SLNode *p;int j;p=head;j=-1;while(p->next!=head&&j<i){p=p->next;j++;}if(j!=i){printf("取出元素位置參數錯!");return 0;}*x=p->data;return 1;
}
void Destroy(SLNode **head){SLNode *p,*p1;p=*head;while(p!=NULL){p1=p;p=p->next;free(p1);}*head=NULL;
}