⑴ c語言裡面的鏈表是什麼
C語言裡面的鏈表是一種數據結構
是一種線形的存儲結構
鏈表和數組一樣,也是將一組同類型的數據組織在一起的一種數據結構
不同的是
數組採用的是順序存儲,依靠數組的首地址和元素的相對地址(下標)來實現訪問。
優點是訪問方便快捷,而缺點是數組是靜態的,不利於實現元素的動態增減。
而鏈表採用的是離散存儲,依靠節點間的指向下一個節點的指針來實現訪問。
其優缺點和數組相反
⑵ C語言中鏈表是怎樣調用的
->運算是間接定址,你用多指針的話會發現指針用->這種調用方式更簡潔
鏈表指針是C語言的一個難點,但也是重點,學懂了非常有用。要仔細講就必須先講變數、指針。
什麼是變數?所謂變數,不要淺顯的認為會變得量就是變數。舉個例子:「教室變不變?」變,因為每天有不同的人在裡面上課,但又不變,因為教室始終在那,沒有變大或變小。這就是變數:有一個不變的地址和一塊可變的存儲空間。正常情況下,我們只看到變數這個房間裡面的東西,也就是其內容,但不會關注變數的地址,但是C語言的指針,就是這個房間的地址。我們聲明變數就相當於蓋了間房子存放東西,我們可以直接觀看房子里的東西,而聲明指針,就是相當於獲得了一個定位器,當用指針指向某個變數時,就是用指針給變數定位,以後我們就可以用指針找到他所「跟蹤」的變數並可以獲得裡面的內容。
至於我們寫代碼的結構體就相當於是有好幾個房子組成的別墅,幾個房子綁定在一起使用。假設現在有很多這種別墅分布在一個大迷宮里,每間別墅里都有一間房子。裡面放了另一個別墅的位置信息,現在你手拿定位器找到了第一棟別墅,從裡面得到了你想要的東西(鏈表的數據部分),然後把下一棟別墅的位置計入你的定位器(p
=
p->next),再走向下一棟別墅……如此走下去,知道走到某地下一棟別墅信息沒有了(p->next
==
NULL),你的旅行結束。這就是鏈表一次遍歷的過程。
aTdPage[ucTdPageIndex]->OnInit
();就相當於一個定位器
⑶ 用c語言創建鏈表
void CreateList_H(Linklist L,int n)中的L是局部變數,你生成的頭結點L不能被返回,應該改為:
Linklist CreateList_H(int n)
調用方式和函數內部返回值都需要相應改動。
⑷ 在C語言中,什麼是鏈表呀
鏈表
鏈表鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,鏈表比較方便插入和刪除操作。
概況
鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,但是並不會按線性的順序存儲數據,而是在每一個節點里存到下一個節點的指針(Pointer)。由於不必須按順序存儲,鏈表在插入的時候可以達到O(1)的復雜度,比另一種線性表:順序錶快得多,但是查找一個節點或者訪問特定編號的節點則需要O(n)的時間,而順序表相應的時間復雜度分別是O(logn)和O(1)。使用鏈表結構可以克服數組鏈表需要預先知道數據大小的缺點,鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。但是鏈表失去了數組隨機讀取的優點,同時鏈表由於增加了結點的指針域,空間開銷比較大。在計算機科學中,鏈表作為一種基礎的數據結構可以用來生成其它類型的數據結構。鏈表通常由一連串節點組成,每個節點包含任意的實例數據(data fields)和一或兩個用來指向明上一個/或下一個節點的位置的鏈接("links")。鏈表最明顯的好處就是,常規數組排列關聯項目的方式可能不同於這些數據項目在記憶體或磁碟上順序,數據的存取往往要在不同的排列順序中轉換。而鏈表是一種自我指示數據類型,因為它包含指向另一個相同類型的數據的指針(鏈接)。鏈表允許插入和移除表上任意位置上的節點,[1]但是不允許隨機存取。鏈表有很多種不同的類型:單向鏈表,雙向鏈表以及循環鏈表。鏈表可以在多種編程語言中實現。像Lisp和Scheme這樣的語言的內建數據類型中就包含了鏈表的存取和操作。程序語言或面向對象語言,如C,C++和Java依靠易變工具來生成鏈表。
編輯本段特點
線性表的鏈式存儲表示的特點是用一組任意的存儲單元存儲線性表的數據元素(這組存儲單元可以是連續的,也可以是不連續的)。因此,為了表示每個數據元素 與其直接後繼數據元素 之間的邏輯關系,對數據元素 來說,除了存儲其本身的信息之外,還需存儲一個指示其直接後繼的信息(即直接後繼的存儲位置)。由這兩部分信息組成一個"結點"(如概述旁的圖所示),表示線性表中一個數據元素 。
編輯本段擴展
根據情況,也可以自己設計鏈表的其它擴展。但是一般不會在邊上附加數據,因為鏈表的點和邊基本上是一一對應的(除了第一個或者最後一個節點,但是也不會產生特殊情況)。不過有一個特例是如果鏈表支持在鏈表的一段中把前和後指針反向,反向標記加在邊上可能會更方便。 對於非線性的鏈表,可以參見相關的其他數據結構,例如樹、圖。另外有一種基於多個線性鏈表的數據結構:跳錶,插入、刪除和查找等基本操作的速度可以達到O(nlogn),和平衡二叉樹一樣。 其中存儲數據元素信息的域稱作數據域(設域名為data),存儲直接後繼存儲位置的域稱為指針域(設域名為next)。指針域中存儲的信息又稱做指針或鏈。 由分別表示,,…, 的N 個結點依次相鏈構成的鏈表,稱為線性表的鏈式存儲表示,由於此類鏈表的每個結點中只包含一個指針域,故又稱單鏈表或線性鏈表.
編輯本段三個鏈表函數(C語言描述)
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
struct Node{
int data;//數據域
struct Node * next;//指針域
}; /************************************************************************************** *函數名稱:insert
*函數功能:在鏈表中插入元素. *輸入:head 鏈表頭指針,p新元素插入位置,x 新元素中的數據域內容 *輸出:無 *************************************************************************************/ void insert(Node * head,int p,int x)
{ Node * tmp = head; //for循環是為了防止插入位置超出了鏈表長度 for(int i = 0;i<p;i++)
{
if(tmp == NULL)
return ;
if(i<p-1)
tmp = tmp->next;
}
Node * tmp2 = new Node;
tmp2->data = x;
tmp2->next = tmp->next;
tmp->next = tmp2;
} /************************************************************************************** *函數名稱:del *函數功能:刪除鏈表中的元素 *輸入:head 鏈表頭指針,p 被刪除元素位置 輸出:被刪除元素中的數據域.如果刪除失敗返回-1 **************************************************************************************/
int del(Node * head,int p)
{
Node * tmp = head;
for(int i = 0;i<p;i++)
{
if(tmp == NULL)
return -1;
if(i<p-1)
tmp = tmp->next;
}
int ret = tmp->next->data;
tmp->next = tmp->next->next;
return ret;
}
void print(Node *head)
{
for(Node *tmp = head;
tmp!=NULL; tmp = tmp->next)
printf("%d ",tmp->data);
printf("\n");
}
int main()
{
Node * head;
head = new Node;
head->data = -1;
head->next=NULL;
return 0;
}
編輯本段結語
C語言是學習數據結構的很好的學習工具。理解了C中用結構體描述數據結構,那麼對於理解其C++描述,Java描述都就輕而易舉了!
編輯本段兩種鏈表形式
一、循環鏈表 循環鏈表是與單鏈表一樣,是一種鏈式的存儲結構,所不同的是,循環鏈表的最後一個結點的指針是指向該循環鏈表的第一個結點或者表頭結點,從而構成一個環形的鏈。 循環鏈表的運算與單鏈表的運算基本一致。所不同的有以下幾點: 1、在建立一個循環鏈表時,必須使其最後一個結點的指針指向表頭結點,而不是象單鏈表那樣置為NULL。此種情況還使用於在最後一個結點後插入一個新的結點。 2、在判斷是否到表尾時,是判斷該結點鏈域的值是否是表頭結點,當鏈域值等於表頭指針時,說明已到表尾。而非象單鏈表那樣判斷鏈域值是否為NULL。
二、雙向鏈表 雙向鏈表其實是單鏈表的改進。 當我們對單鏈表進行操作時,有時你要對某個結點的直接前驅進行操作時,又必須從表頭開始查找。這是由單鏈表結點的結構所限制的。因為單鏈表每個結點只有一個存儲直接後繼結點地址的鏈域,那麼能不能定義一個既有存儲直接後繼結點地址的鏈域,又有存儲直接前驅結點地址的鏈域的這樣一個雙鏈域結點結構呢?這就是雙向鏈表。 在雙向鏈表中,結點除含有數據域外,還有兩個鏈域,一個存儲直接後繼結點地址,一般稱之為右鏈域;一個存儲直接前驅結點地址,一般稱之為左鏈域。
⑸ 計算機c語言中什麼是鏈表
簡單來說就是「承上啟下」,區別於正常數組,存儲的時候不是一連串連續的內存地址。
鏈表的特點在於結點,struct stu{
int num;
int score;
struct stu *next;
}
這就是一個簡單的鏈表,
上邊兩個是數據域,最後一個是指針域
指針域交代了下一個數據是存在哪裡的,
這樣計算機就可以直接去找到了。
這樣便於插入和刪除,缺點就是同等的空間下,鏈表存的數據少,因為他多了指針域。
⑹ C語言 鏈表
pb=(TYPE*) malloc(LEN);這點不明白起什麼作用??是什麼意思?
是不明白malloc的使用?大致講來就是分配一個內存空間,因為鏈表創建需要動態分配內存,改內存空間的大小是LEN 並使pb指向這個內存空間
pf=head=pb; //i=0是輸入num和age第一次循環的意思嗎?然後return(head),後面=pf是不是多餘?ph已經賦值給head啦為何還要賦值給pf?
看清楚for語句下的花括弧所包含了多少語句。
for(i=0;i<n;i++)
{
pb=(TYPE*) malloc(LEN);
printf("input Number and Age\n");
scanf("%d%d",&pb->num,&pb->age);
if(i==0)
pf=head=pb;
else pf->next=pb; return(head)
pb->next=NULL;
pf=pb;
}
這個整體是一個循環,第一次循環包括輸入語句,以及if語句里的內容,之後的循環包括輸入語句及else里的內容。return head是在整個函數執行完畢後才return,也就是將循環體內所有語句全部執行完畢才會return
pf的作用是指向當前鏈表的尾節點。由於函數需要返回鏈表的表頭head,所以不宜使用head來進行指示,所以採用一個變數pf來進行指示。
else pf->next=pb; // else 好像和head沒有什麼聯系??如何第一次循環之後還有循環呢?並沒有賦值給head 怎麼return(head)???//
除了i=0時,也就是當第一個節點插入時,head才會被賦值,並且之後的操作不會對其產生改變。因為表頭是固定的。第一次循環之後執行else麗的語句,pf->next=pb; 將已有的鏈表的尾節點的next指針指向剛創建得節點,pb->next=NULL,將當前鏈表的尾節點的next指針賦為空。pf=pb,將pf再次指向加入新節點之後的鏈表的尾節點
⑺ c語言鏈表
指針在x86系統里大小是32位4個位元組,在64位系統是8位元組大小。指針好比一個盒子,盒子里有個東西也就是它指向的內容,內容是一個實體對象的首地址。盒子本身不能存放實體對象,就好比盒子里有張名片,通過名片你可以找到這個人,總不能把人放盒子里吧。
得有這個人然後把找到這個人的名片放盒子里。
⑻ C語言鏈表概念
struct node
{
int data;
struct node *next;
}
這個是一個鏈表的定義,next就是本身的一個指針
可以這么理解,鏈表就是一串珠子,每個珠子就是一個結構體,next就是串珠子的線
⑼ c語言鏈表的用途是什麼
1、鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,鏈表比較方便插入和刪除操作。
2、常式:
/*
*對鏈表的綜合操作
*功能有建立,排序,插入,刪除,輸出
*/
#include<stdio.h>
#include<malloc.h>
typedefintElemType;
typedefstructNodeType
{
ElemTypedata;
structNodeType*next;
}NodeType,*LinkType;
LinkTypecreate()
{//建立鏈表,返回鏈表的首地址,頭結點沒有數據
LinkTypehead,p1,p2;
head=(LinkType)malloc(sizeof(NodeType));
p1=head;
while(p1->data!=0)//當data=0時鏈表結束
{
p2=p1;
p1=(LinkType)malloc(sizeof(NodeType));
printf("Enterstudent'sinformation: data=");
scanf("%d",&p1->data);
p2->next=p1;
}
p2->next=NULL;
free(p1);
return(head);
}
voidoutput(LinkTypehead)
{//鏈表的輸出,接收鏈表的首地址
head=head->next;
while(head!=NULL)
{
printf("data=%d ",head->data);
head=head->next;
}
}
LinkTypesort(LinkTypehead)
{//鏈表排序,接收鏈表首地址,返回鏈表首地址
LinkTypeph,p1;
ElemTypetemp;
ph=head->next;
p1=head->next;
while(p1->next!=NULL)//冒泡法
{
ph=head;
while(ph->next!=NULL)
{
if(ph->data>ph->next->data)//按data由小到大排序
{
temp=ph->data;
ph->data=ph->next->data;
ph->next->data=temp;
}
ph=ph->next;
}
p1=p1->next;
}
return(head);
}
LinkTypedel(LinkTypehead)
{//刪除結點,接收鏈表的首地址,返回鏈表的首地址
ElemTypeDelData;
LinkTypeph,p;
ph=head->next;
printf("Enterthedatayouwanttodel: DelData=");
scanf("%d",&DelData);
while(ph!=NULL&&ph->data!=DelData)//尋找要刪除的結點
{
p=ph;
ph=ph->next;
}
if(ph==NULL)//沒有找到要刪除的結點
{
printf("Entererror! ");
return(head);
}
else
{
if(ph==head->next)//刪除頭結點
{
head->next=ph->next;
}
else//刪除其它結點
{
p->next=ph->next;
}
}
free(ph);
return(head);
}
LinkTypeinsert(LinkTypehead)
{//插入結點,接收鏈表首地址,返回鏈表首地址
LinkTypeph,p,insert,temp;
insert=(LinkType)malloc(sizeof(NodeType));
printf("Enterthedatayouwanttoinsert: data=");
scanf("%d",&insert->data);
ph=head->next;
while(ph!=NULL&&ph->data<insert->data)//尋找插入的位置
{
p=ph;
ph=ph->next;
}
if(head->next->data>insert->data)//插入頭部
{
temp=head->next;
head->next=insert;
insert->next=temp;
}
else//插入到其它地方
{
p->next=insert;
insert->next=ph;
}
return(head);
}
voidmain()
{
LinkTypehead;
head=create();
output(head);
printf(" ");
head=sort(head);
output(head);
printf(" ");
head=del(head);
output(head);
printf(" ");
head=insert(head);
output(head);
}
⑽ C語言鏈表操作
包括鏈表的創建刪除添加和釋放操作!!
#include<stdio.h>
#include<stdlib.h>
struct node *create();
void print_list(struct node *head);
struct node * insert_node(struct node *h,int x,int y);
struct node * delete_node(struct node *h,int z);
void shifang(struct node *head);
struct node
{
char data;
struct node *next;
};
void main()
{
struct node *head;
int x,y,z;
head=create();
print_list(head);
printf("\n輸入插入結點的位置的值和插入的數值:");
scanf("%d%d",&x,&y);
head=insert_node(head,x,y);
print_list(head);
printf("\n輸入要刪除的結點:");
scanf("%d",&z);
head=delete_node(head,z);
print_list(head);
printf("\n釋放鏈表.\n");
}
struct node *create() //建立鏈表函數
{
printf("請輸入各節點(以-1結尾):\n");
int x;
//定義指針*head,*tail,*s;
struct node *head,*tail,*s;
//head和tail初始化,生成一個頭結點
head=tail=(struct node *)malloc(sizeof(struct node));
//在循環中,生成新結點、賦值、連接、尾指針後移
scanf("%d",&x);
while(x!=-1)
{
s=(struct node *)malloc(sizeof(struct node));
s->data=x;
tail->next=s;
tail=s;
scanf("%d",&x);
}
//尾結點的指針域賦NULL
tail->next=NULL;
return head;
}
void print_list(struct node *head) //輸出鏈表函數
{
//定義工作指針*p並賦初值p=head->next;即指向第一個結點
struct node *p;
p=head->next;
//判斷鏈表是否為空,空:輸出空表的信息,否則:輸出所有結點
if(p==NULL)
printf("The list is NULL.");
else
//在循環中輸出當前結點,工作指針後移
{
printf("head->");
while(p!=NULL)
{
printf("%d->",p->data);
p=p->next;
}
printf("end.");
}
}
struct node * insert_node(struct node *h,int x,int y) //添加結點函數
{
struct node *p,*q,*s;
//生成要插入的新結點
s=(struct node *)malloc(sizeof(struct node));
s->data=y;
q=h;
p=h->next;
//查找要插入結點的位置
while((p!=NULL)&&(p->data!=x))
{
q=p;
p=p->next;
}
//插入結點
q->next=s;s->next=p;
return(h);
}
struct node * delete_node(struct node *h,int z) //刪除結點函數
{
struct node *p,*q;
q=h;
p=h->next ;
//查找要刪除結點的位置
if(p!=NULL)
{
while((p!=NULL)&&(p->data!=z))
{
q=p;
p=p->next;
}
//釋放結點
if(p->data ==z)
{
q->next=p->next ;
free(p);
}
}
return(h);
}
void shifang(struct node *head) //釋放鏈表函數
{
struct node *p;
//逐個釋放結點
while(head!=NULL)
{
p=head;
head=head->next;
free(p);
}
}