// List1.cpp : Defines the entry point for the console application.
//
/*
C語言下的升序鏈表的基本操作 List1.cpp
-------------------------------------
作者: Software Engineering @ HIT
1093710210 Alex
時間: 2010.9.10
-------------------------------------
*/
//黃虎傑院長在數據結構基礎與算法課上留的一個小練習。。。好幾天了,一直沒寫,感覺不會太難,沒想到一寫還真是把自己整的挺蒙的,還要多練啊
//不過寫鏈表的過程中學到了很多經驗。。不要迷信網絡。。感覺好亂。。還是準備一張白紙一支筆。。自己畫得明白= =
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
struct List
{
int data;
struct List *next;
};
void menu();
struct List *Create(struct List *h) ; //創建和插入升序鏈表
void Display(struct List *h); //輸出鏈表信息
struct List *Delete_all(struct List *h); //刪除整個鏈表
struct List *Delete(struct List *h , int xdata) ; //刪除鏈表中結點
struct List *Search(struct List *h , int xdata) ; //查找某節點位置,本例中返回了其地址
struct List *Revers(struct List *h) ; //實現鏈表的逆序
int main(int argc, char* argv[])
{
int choice,i =0;
struct List *position,*MyList = NULL;
int xdata;
menu();
while (1)
{
printf("請輸入操作: ");
scanf("%d",&choice);
switch (choice)
{
case 1:
printf("Please input the node: /n");
MyList = Create( MyList);
break;
case 2:
printf("Please input the node you want to delete: /n");
scanf("%d",&xdata);
MyList = Delete( MyList,xdata);
break;
case 3:
printf("Please input the node you want to locate: /n");
scanf("%d",&xdata);
position = Search(MyList,xdata);
printf("the node position is %d",position);
break;
case 4:
Display(MyList);
break;
case 5:
MyList = Revers( MyList);
printf("The links reversed is :/n");
Display(MyList);
break;
case 6:
MyList = Delete_all(MyList);
printf("Link deleted ! /n");
break;
default:
printf("wrong!");
}
}
return 0;
}
void menu()
{
printf("單向升序鏈表的操作/n");
printf("-----------------------------------------/n");
printf("1 -> 創建升序鏈表鏈表或插入節點升序鏈表中/n");
printf("2 -> 刪除鏈表中的某個節點/n");
printf("3 -> 返回某個節點的地址指針/n");
printf("4 -> 輸出線性鏈表/n");
printf("5 -> 實現單向鏈表逆序/n");
printf("6 -> 刪除整個線性表/n");
}
/*
函數功能:升序輸入鏈表函數
函數參數:結構體指針
返回值 : 結構體指針
*/
struct List *Create(struct List *h)
{
struct List *newpr = NULL;
struct List *temp = h;
struct List *flag = NULL;
int data;
newpr = (struct List *)malloc(sizeof (struct List));
if (newpr == NULL) //用於檢查是否申請動態空間成功
{
printf("memory error");
exit(0);
}
scanf("%d",&data);
newpr->data = data;
newpr->next = NULL;
if (h == NULL)
h = newpr;
else
{
while (temp->next != NULL && temp->data <= data ) //老師上課用的<,我感覺還是應該用<=這樣可以解決重複輸入相同data無效的問題
{
flag = temp; //flag用於記錄合適的插入點前的位置
temp = temp->next;
}
if (temp->data >data) //用於檢查時否在兩個值之間,可以看出是否到了鏈表的末尾
{
if (temp == h) //說明在表頭前插入數據,產生新的表頭
{
newpr->next = h ;
h = newpr ;
}
else
{
temp = flag; //把當前的位置前移一下,移到插入點前面
newpr->next = temp->next;
temp->next = newpr;
}
}
else //在表末插入
{
temp->next =newpr;
}
}
return h;
}
/*
函數功能:輸出線性表
函數參數:結構體指針
返回值 : void
*/
void Display(struct List *h)
{
struct List *p = h;
int counter = 1;
printf("Position: Data /n");
while (p != NULL)
{
printf(" %d " ,counter);
printf(": %d/n", p->data );
counter++;
p = p->next;
}
}
/*
函數功能:刪除某個結點
函數參數:結構體指針,要刪除節點數據int
返回值 : 結構體指針
*/
struct List *Delete(struct List *h , int xdata)
{
struct List *temp = h;
struct List *flag = h;
if ( h == NULL)
{
printf("no link !");
return (h);
}
while (temp->data != xdata && temp->next !=NULL)
{
flag = temp;
temp = temp->next;
}
if (xdata == temp->data) //檢查是到了末尾還是已經找到相應節點
{
if (temp == h) //首節點的情況
{
h = temp->next;
}
else
{
flag->next=temp->next;
}
free (temp);
}
else
printf("NO NODE!/n");
return h;
}
/*
函數功能:返回某節點的地址
函數參數:結構體指針,要查找節點數據int
返回值 : 結構體指針
*/
struct List *Search(struct List *h , int xdata)
{
struct List *temp = h;
if ( h == NULL)
{
printf("no link !");
return (h);
}
while (temp->data != xdata && temp->next !=NULL)
{
temp = temp->next;
}
if (xdata == temp->data) //檢查是到了末尾還是已經找到相應節點
return temp;
else
printf("NO Location!/n");
return temp;
}
/*
函數功能:單向鏈表的逆序
函數參數:結構體指針
返回值 : 結構體指針
*/
struct List *Revers(struct List *h)
{
struct List *back,*p,*newhead = NULL;
p = h;
while ( p != NULL)
{
back = p->next; //記錄當前節點的下一位置,以防鏈表丟失
p->next = newhead ; //當前節點開始指向前一個節點,此時的newhead初始化一定爲NULL
newhead = p ; //newhead指針緊跟着p向後移,一直到最後p指向NULL了,此時newhead爲逆序的首結點
p= back; //找到下一個節點
}
return newhead;
}
//感受:從網上看了一個,分明是弄錯指針p後移時,沒有記錄下一節點的位置,造成鏈表的斷開
//他的做法是 back = p;
// p->next = newhead ;
// newhead = p ;
// p= back->next; 這樣的話表面上是back記錄了下一個節點,實際上他指向的P的next已經被修改爲NULL,使得最後一行語句無效
struct List *Delete_all(struct List *h)
{
struct List *temp = NULL;
while (h!= NULL)
{
temp = h;
h=temp->next;
free(temp);
}
return h;
}
升序鏈表的基本操作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.