#include <stdio.h>
#include <stdlib.h>
typedef int Element;
typedef char(*Status)[10];
#define ERROR "error"
#define OK "ok";
// 定義一個線性單鏈表結構
typedef struct Node{
Element data;
struct Node *next;
}Node,*LinkedList;
// 初始化一個線性單鏈表
LinkedList init(){
Node *l;
l = (Node *)malloc(sizeof(Node));
l->next = NULL;
return l;
}
// 創建一個線性單鏈表
void create(LinkedList l){
for(int i = 2; i < 5; i++){
LinkedList p;
p = (LinkedList)malloc(sizeof(Node));
p->data = i;
p->next = l->next;
l->next = p;
}
}
// 插入數據到線性單鏈表中(頭插法)
void insertHead(LinkedList l,Element e){
LinkedList p;
p = (LinkedList)malloc(sizeof(Node));
p->data = e;
p->next = l->next;
l->next = p;
}
// 插入數據到線性單鏈表中(尾插法)
void insertTail(LinkedList L,Element e){
LinkedList p,r;
//r始終指向終端結點,開始時指向頭結點
r = L;
//就是將這個尾指針指向最後一個元素
while(r->next){
r = r->next;
}
//申請新的結點
p = (LinkedList)malloc(sizeof(Node));
p->data = e;
// 將表尾終端節點的指針指向新節點
r->next = p;
// 將當前的新節點定義爲表尾終端節點
r = p;
//表示當前鏈表結束
r->next = NULL;
}
// 從線性單鏈表中取出指定位置的數據(位置從0開始)
Status LinkedListGet(LinkedList l,int i,Element *e){
LinkedList p = l->next;
int j = 0;
while(p&&j<i){
p = p->next;
j++;
}
if(!p||j>i){
return ERROR;
}
*e = p->data;
return OK;
}
// 線性單鏈表的指定位置插入數據
Status LinkedListInsert(LinkedList L,int index,Element e){
LinkedList pre,p; //pre爲前驅結點
pre = L->next;
int tempi = 1;
while(pre&&tempi<index){
// 就是再尋找第i-1個節點
pre = pre->next;
++tempi;
}
if(!pre||tempi>index){
// 第index個節點不存在
return ERROR;
}
p = (LinkedList)malloc(sizeof(Node));
p->data = e;
p->next = pre->next;
pre->next = p;
return OK;
}
// 刪除線性單鏈表的指定位置元素
Status LinkedListRemove(LinkedList L,int index,Element *e){
LinkedList pre,p;
//pre爲頭指針
pre = L->next;
int tempi = 1;
// 就是在尋找第i-1個節點
while(pre&&tempi<index){
pre = pre->next;
++tempi;
}
if(!(pre->next)||tempi>index){
// 第index個節點不存在
return ERROR;
}
p = pre->next;
pre->next = p->next;
*e = p->data;
//將p的內存進行釋放
free(p);
return OK;
}
// 查找線性單鏈表的指定元素,存在則返回這個元素的地址(不是所在的位置哦),不存在返回NULL;
Node * LinkedListIndexOf(LinkedList L,Element e){
LinkedList p;
if(!L){
return ERROR;
}
p = L;
while(p&&p->data!=e){
p = p->next;
}
return p;
}
// 清空線性表
Status LinkedListClear(LinkedList L){
LinkedList p,q;
p = L->next;
while(p){
q = p->next;
free(p);
p = q;
}
// 將頭節點的指針域置爲空。
L->next = NULL;
return OK;
}
// 打印出線性單鏈表的所有數據元素
void toString(LinkedList l){
printf("[");
l = l->next;
while(l){
printf("%d",l->data);
l=l->next;
if(l){
printf(",");
}
}
printf("]\n");
}
int main(){
LinkedList L = init();
create(L);
//insertHead(L,5);
insertTail(L,1);
Element a = -1;
// Element *a = &1;不要幹這麼傻逼的事情,常數的地址賦值給指針變量沒有任何意義,c語言不允許這麼做。
// Element *a = 1;表示*a所存儲的地址值爲1。
// 指針是用來存放地址的!地址就是個常數!雖然這樣是能編譯通過的!(準確地說,只能賦值0,其他的都不合法)。
// 但是,這樣執行會出錯(段錯誤)的!因爲指針本來是存放地址的,而你卻存放了一個常數(即一個不合法的地址),
// 這樣就會使指針指向不確定的內存單元(非法訪問),從而出現錯誤!
Element *intPoint=&a;
// *intPoint=a;等同於:int *intPoint; *intPoint = a;
// 這個指針都沒指向任何地址,也就不存在值,取也就會出錯
// 取出鏈表中第0個數據元素(下標從0開始)
Status res = LinkedListGet(L,0,intPoint);
printf("Get() res is :%s,element is %d\n",res,*intPoint);
LinkedListInsert(L,2,5);
res = LinkedListRemove(L,3,intPoint);
printf("remove status :%s,remove Element is %d\n",res,*intPoint);
Node *indexRes = LinkedListIndexOf(L,7);
printf("..index Memory address :%d\n",indexRes);
//LinkedListClear(L);
toString(L);
return 0;
}
不足和錯誤之處還請多多指正,謝謝!