#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct List
{
ElemType data; //數據域
struct List *next; //指針域
} Node, *LinkedList;
//頭插法創建鏈表,將新增節點插頭第一個節點之前
LinkedList createH()
{
Node *L = (Node *)malloc(sizeof(Node)); //申請一個數據域爲空的頭節點
if(L == NULL)
{
printf("分配空間失敗!\n");
exit(0);
}
L->next = NULL;
int nodeNum;
printf("輸入節點數量: ");
scanf("%d",&nodeNum);
printf("\n");
printf("輸入節點數據: ");
for(int i=0; i<nodeNum; i++) //依次插入節點
{
ElemType data;
scanf("%d",&data);
Node *p = (Node *)malloc(sizeof(Node)); //申請節點空間
if(p == NULL)
{
printf("分配空間失敗!\n");
exit(0);
}
p->data = data;
p->next = L->next; //頭結點指向新增節點
L->next = p; //新增節點指向第一個節點
}
return L; //返回頭節點
}
//尾插法建立鏈表,新增節點插入最後一個節點之後
LinkedList createT()
{
Node *L, *pre;
L = (Node*)malloc(sizeof(Node)); //爲頭結點申請空間
if(L == NULL) //判斷是否申請失敗
{
printf("申請內存失敗!\n");
exit(0);
}
L->next = NULL;
pre = L; //pre始終指向鏈表尾部
int nodeNum;
printf("輸入節點數量: ");
scanf("%d",&nodeNum);
printf("\n");
printf("輸入節點數據: ");
ElemType data;
for(int i=0; i<nodeNum; i++)
{
scanf("%d",&data);
Node *p = (Node *)malloc(sizeof(Node)); //爲新增節點分配空間
if(p == NULL)
{
printf("申請內存失敗!\n");
exit(0);
}
p->data = data;
p->next = NULL;
pre->next = p; //新增節點插入鏈表尾部
pre = pre->next; //pre移到尾部
}
return L;
}
//在指定位置插入節點
void insertNode(LinkedList L)
{
int pos; //插入位置
ElemType data; //插入節點數據
printf("輸入插入位置, 插入節點的數據: ");
scanf("%d %d",&pos,&data);
LinkedList p = L; //指針p查找插入位置
int cnt = 0;
while(cnt<pos)
{
if(p->next == NULL && cnt<pos) //判斷插入位置是否大於鏈表長度
{
printf("超出鏈表長度\n");
return;
// exit(0);
}
p = p->next; //指針p一直滑動到要插入的位置
cnt++;
}
Node *r = (Node *)malloc(sizeof(Node)); //爲插入節點申請空間
r->data = data;
r->next = p->next; //插入鏈表對應位置
p->next = r;
}
//刪除鏈表中的一個數據爲x的節點
void deleteNode(LinkedList L)
{
ElemType data;
printf("輸出要刪除的數據: ");
scanf("%d",&data);
LinkedList p = L; //p節點進行查找
LinkedList r = L->next; //r表示p節點後的一個節點
if(L->next==NULL) //判斷鏈表是否爲空
{
printf("鏈表爲空!\n");
return;
// exit(0);
}
while(r->next!=NULL) //找到要刪除數據的位置
{
if(r->data == data) break;
p = p->next;
r = r->next;
}
if(r->data != data) //判斷鏈表中是否存在要刪除的數據
{
printf("鏈表中未找到要刪除的數據!\n");
// exit(0);
return;
}
p->next = r->next; //刪除操作
free(r); //釋放刪除節點的內存
}
//將鏈表各個節點的數據打印出來
void printList(LinkedList L)
{
LinkedList p;
if(L->next==NULL) { //判斷鏈表是否爲空
printf("鏈表爲空!\n");
return;
}
p = L->next;
while(p->next!=NULL)
{
printf("%d->",p->data);
p = p->next;
}
printf("%d\n",p->data);
}
void reverseList(LinkedList L)
{
if(L==NULL) //判斷鏈表是否爲空
{
printf("鏈表爲空!\n");
return;
}
if(L->next==NULL) //只有一個節點時,反轉即本身,無需反轉
{
printf("只有一個元素,不需反轉\n");
return;
}
LinkedList p, q, r;
p = L;
q = L->next;
r = q->next;
q->next=NULL; //第一次循環時,將q->next(即反轉後的尾節點)指向null
p = q;
q = r;
while(q!=NULL)
{
r = q->next;
q->next = p;
p = q;
q = r;
}
L->next = p;
}
int main()
{
LinkedList L;
int option;
printf("輸入要進行的操作\n");
printf("-----------------\n");
printf("1 頭插法創建鏈表\n");
printf("2 尾插法插法創建鏈表\n");
printf("3 插入節點\n");
printf("4 刪除節點\n");
printf("5 反轉鏈表\n");
printf("0 退出\n");
while(scanf("%d",&option)&&option!=0) //輸入指令
{
switch (option)
{
case 1:
L = createH(); //頭插法創建鏈表
printList(L); //打印鏈表
break;
case 2:
createT(); //尾插法創建鏈表
printList(L); //打印鏈表
break;
case 3:
insertNode(L); //插入節點
printList(L); //打印鏈表
break;
case 4:
deleteNode(L); //刪除節點
printList(L); //打印鏈表
break;
case 5:
reverseList(L); //反轉鏈表
printList(L); //打印鏈表
}
printf("輸入要進行的操作: ");
}
return 0;
}
代碼參考於https://www.cnblogs.com/newwy/archive/2010/10/10/1847456.html