資料結構--線性表(單鏈表C語言實現)
阿新 • • 發佈:2019-01-28
//單鏈表的練習
#include "stdlib.h"
#include "stdio.h"
void printLinkList(struct node *h);
//單鏈表資料結構
typedef struct node {
int data; //資料域
struct node *next; //指標域
}Lnode,*LinkList;
//建立連結串列 帶頭結點
LinkList createLinkList(int n)
{
struct node *h, *p, *q;
int i;
p=(struct node *)malloc (sizeof(struct node));
h=p;
q=p;
for(i=0;i<n;i++)
{
p=(struct node *)malloc(sizeof(struct node));
printf("請輸入第%d個元素的值:", i+1);
scanf("%d", &(p->data));
q->next=p;
q=p;
}
q->next=NULL;
return h;
}
//查詢連結串列中某個資料
//查詢操作不涉及修改連結串列中的節點位置,所以依然返回之前的頭結點,不作修改
LinkList FindElem(LinkList h){
LinkList p = h->next;
int data;
printf("請輸入要查詢的元素:\n");
scanf("%d",&data);
int i = 1;
int flag = 0;
while(p!= NULL){
if (data == p->data){
printf("查詢到的元素為%d\n",data);
flag = 1;
break;
}
p = p->next;
i++;
}
if (flag == 1){
printf("查詢到的元素在第%d個位置\n",i);
} else{
printf("沒找到相關元素\n");
}
return h;
}
//向連結串列中插入資料
LinkList InsertList(LinkList h){
LinkList p = h->next;
LinkList q;
q = (LinkList)malloc(sizeof(Lnode));//為插入的資料申請一個空間
int data,n;
printf("請輸入插入的資料\n");
scanf("%d",&data);
printf("請輸入要插入的位置\n");
scanf("%d",&n);
int j = 1;
if (n == 1){
q->next = p->next;
q->data = data;
p->next = q;
return p;
}
while(p!= NULL && n > j+1){
p = p->next;
j++;
}
printf("%d\n",p->data);
if (p ==NULL){
printf("引數錯誤");
return NULL;
}
q->next = p->next;
q->data = data;
p->next = q;
return h;
}
LinkList Insert_Linklist(LinkList h)
//在有序單鏈表中插入元素,連結串列仍然有序
{
LinkList p, q, s;
int x;
printf("請輸入要插入的元素:\n");
scanf("%d",&x);
q = h;
p = h->next;
while(p)
{
if(p->data <= x)
{
q = p;
p = p->next;
}
else
break;
}
s = (LinkList)malloc(sizeof(Lnode));
if(!s) return 0;
s->data = x;
q->next = s;
s->next = p;
return h;
}
//插入資料操作2
LinkList InsertList2(LinkList h){
LinkList p = h->next;
LinkList q;
printf("請輸入要插入的元素:\n");
int data,n;
scanf("%d",&data);
printf("請輸入要插入的元素的位置:\n");
scanf("%d",&n);
if(n == 1){//新節點插入到表頭
q = (LinkList)malloc(sizeof(Lnode));//為將要插入的元素申請一個空間
q->data = data;
q->next = p;
h->next = q;
return h;//返回新表頭指標
} else{
//查 找第n-1個節點
int i = 1;
int flag = 0;
while(p!= NULL){
if (n == i+1){
flag = 1;
break;
}
p = p->next;
i++;
}
printf("%d\n",p->data);
if (p == NULL){
printf("引數錯誤\n");
return NULL;
} else {
q = (struct node *)malloc(sizeof(struct node));
q->data = data;
q->next = p->next;
p->next = q;
return h;
}
return h;
}
return h;
}
//刪除連結串列中值為X的資料
LinkList DeleateList(LinkList h){
LinkList p = h->next;
LinkList q = h;
printf("請輸入要刪除的元素值\n");
int data;
scanf("%d",&data);
while(p != NULL){
if(p->data == data){
q->next = p->next;
free(p);//將p節點釋放掉
p = q->next;//p再指向刪除元素所指向的元素
}else{
q = p;
p = p->next;
}
}
return h;
}
//刪除連結串列中所有值為偶數的節點
LinkList DelEven_LinkList(LinkList h){
LinkList p, q;
q = h;
p = h->next;
while(p)
{
if(p->data % 2 == 0)
{
q->next = p->next;
free(p);
p = q->next;
}
else
{
q = p;
p = p->next;
}
}
return h;
}
//連結串列清空
LinkList ClearList(LinkList h){
LinkList p = h->next;
LinkList q;
while(p != NULL){
q = p;
p = p->next;
free(p);
}
h->next = NULL;
return h;
}
//連結串列逆轉
LinkList Reversed(LinkList h){
LinkList q=h->next;
LinkList p=NULL;
LinkList pNext;
while (NULL != q) {
pNext=q->next;
q->next = p;
p=q;
q=pNext;
}
h->next = p;
return h;//返回頭指標
}
//計算單鏈表的長度,並遍歷單鏈表輸出單鏈表表的內容
void printLinkList(struct node *h)
{
LinkList p=h->next;
int i = 0;
while(p!=NULL)
{
printf("%d ", p->data);
p=p->next;
i++;
}
printf("\n");
printf("單鏈表的長度為:%d\n",i);
}
void menu(){
printf("1:連結串列建立\n");
printf("2:插入操作\n");
printf("3:刪除操作\n");
printf("4:查詢操作\n");
printf("5:連結串列逆轉\n");
printf("6:連結串列清空\n");
printf("7:刪除值為偶數的節點\n");
printf("0:退出\n");
}
int main()
{
LinkList head;
int m;
while(1){
menu();
printf("請輸入操作的序號:\n");
scanf("%d",&m);
switch (m) {
case 1:
int n;
//struct node *head;
printf("請輸入元素的個數:");
scanf("%d", &n);
head=createLinkList(n);//得到頭結點
printf("\n單鏈表建立完畢。。。\n");
printf("\n單鏈表的元素如下:\n");
printLinkList(head);
break;
case 2:
//向連結串列中插入資料
//head = InsertList(head);
head = Insert_Linklist(head);//有序插入
printf("插入資料的連結串列後的結果為:");
printLinkList(head);
break;
case 3:
//連結串列刪除操作
head = DeleateList(head);
printLinkList(head);
break;
case 4:
//查詢連結串列中某個元素並輸出其所在位置
FindElem(head);
break;
case 5:
//連結串列反轉
Reversed(head);
printf("反轉過後的連結串列如下:\n");
printLinkList(head);
break;
case 6:
//清空連結串列
ClearList(head);
printf("連結串列清空完成:\n");
printLinkList(head);
break;
case 7:
DelEven_LinkList(head);
printLinkList(head);
break;
case 0:
return 0;
break;
default:
break;
}
}
}