1. 程式人生 > >建立連結串列的三種演算法(C語言實現)——正向、逆向、遞迴

建立連結串列的三種演算法(C語言實現)——正向、逆向、遞迴

連結串列分為靜態連結串列和動態連結串列,本文主要討論動態連結串列的建立。

靜態連結串列是用兩個陣列模擬一個連結串列,其中一個數組中存實際資料,可以稱之為資料陣列。另一個數組中存資料陣列中各元素的下標,我們稱之為地址陣列(注意地址陣列中存的並不是地址值,而是整形的數)。靜態陣列的好處是避免了指標的操作,不足之處是佔用了較多的儲存空間。

靜態連結串列不是本文討論的重點,下面主要討論建立動態連結串列的三個常用演算法。

這裡連結串列每個節點中的資料域以一個int型的資料為例,並且資料是通過陣列傳入,而不是使用者直接輸入的。

此外,本文只是說明建立連結串列的方法,建立成功之後無法再次在連結串列中加入節點。

建立連結串列的方法大致有三種:

1.正向建立連結串列:最容易理解,即為每次在連結串列末尾插入一個節點。

2.逆向建立連結串列:即為每次在原連結串列的頭結點之前插入一個節點。

3.遞迴建立連結串列:遞迴建立連結串列的特點在於,遞迴呼叫時申請空間並對資料域賦值,遞迴返回時掛鏈。所以創建出來的是一個逆向的連結串列。

#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
	int data;
	struct Node *next;
}ElemSN;

ElemSN* CreatLink1(int data[],int n);//正向(尾插法)建立無表頭連結串列
ElemSN* CreatLink2(int data[],int n);//逆向(頭插法)建立無表頭連結串列
ElemSN* CreatLink3(int data[],int n);//遞迴法建立連結串列

void PrintLink(ElemSN *h);//正向輸出連結串列的資料
void DeleteLink(ElemSN *h);//刪除連結串列 
int main(void)
{
	ElemSN *head1=NULL,*head2=NULL,*head3=NULL;
	int data[8]={3,2,5,8,4,7,6,9};
	head1=CreatLink1(data,8);//正向(尾插法)建立無表頭連結串列
	PrintLink(head1);
	head2=CreatLink2(data,8);//逆向(頭插法)建立無表頭連結串列
	PrintLink(head2);
	head3=CreatLink3(data,8);//遞迴法建立連結串列
	PrintLink(head3);
	DeleteLink(head1);//刪除連結串列 
	DeleteLink(head2);
	DeleteLink(head3);
	return 0;
}

ElemSN* CreatLink1(int data[],int n)//正向(尾插法)建立無表頭連結串列
{
	ElemSN *h=NULL,*p=NULL,*t=NULL;
	int i;
	for(i=0;i<n;i++){
		p=(ElemSN *)malloc(sizeof(ElemSN));
		p->data=data[i];
		p->next=NULL;
		if(h==NULL){
			t=h=p;
		}
		t=t->next=p;
	}
	return h;
}
ElemSN* CreatLink2(int data[],int n)//逆向(頭插法)建立無表頭連結串列 
{
	ElemSN *h=NULL,*p=NULL;
	int i;
	for(i=n-1;i>=0;i--){
		h=(ElemSN *)malloc(sizeof(ElemSN));
		h->data=data[i];
		if(!h){//if(h==NULL)
			p=h;
			h->next=NULL;
		}
		h->next=p;
		p=h;
	}
	return h;
}
ElemSN* CreatLink3(int data[],int n)//遞迴法建立連結串列
{
	ElemSN *p=NULL;
	if(n==0)
		return NULL; 
	p=(ElemSN *)malloc(sizeof(ElemSN));
	p->data=data[n-1];	
	p->next=CreatLink3(data,n-1);
	return p;
}

void PrintLink(ElemSN *h)//正向輸出連結串列的資料 
{
	ElemSN *p=NULL;
	for(p=h;p!=NULL;p=p->next){
		printf("%4d",p->data);
	}
	printf("\n連結串列輸出結束!\n");
}

void DeleteLink(ElemSN *h)//刪除連結串列
{
	ElemSN  *delp=NULL,*q=NULL;
	delp=h->next;
	h->next=NULL;
	while(delp!=NULL){
		q=delp->next;
		free(delp);
		delp=q;
	} 
}