考研資料結構複習之線性表(二)
阿新 • • 發佈:2018-11-01
單鏈表的學習
#pragma once
typedef char DataType;
class SSeqListTest
{
public:
SSeqListTest();
~SSeqListTest();
};
typedef struct Node {
DataType data;
struct Node *next;
}ListNode,*LinkList;
void InitLinkList(LinkList *head);
bool IsLinkListEmpty(LinkList head);
ListNode *Get(LinkList head,int i);
ListNode *LocateElem(LinkList head,DataType e);
int LocatePosition(LinkList head,DataType e);
int InsertList(LinkList head,int i,DataType e);
int DeleteList(LinkList head,int i,DataType *e);
int ListLength(LinkList head);
void DestroyList(LinkList head);
完整的實現程式碼如下:
#include "SSeqListTest.h"
#include<malloc.h>
#include<iostream>
using namespace std;
SSeqListTest::SSeqListTest()
{
}
SSeqListTest::~SSeqListTest()
{
}
/*這裡初始化的函式為void InitLinkList(LinkList * head);
它的引數為LinkList * head,媽啊,相當於int **P,
你需要理解透徹,不理解透徹的話也可以參考之前的線性表的初始化:
線性表的初始化:
void InitList(SeqList * L)
{
L->length = 0;
}
所以可以完全照搬。
但是在考研的資料結構中製作節點有兩種方式:
拿簡單的順序表舉例子:
(1)直接製作:SeqList L
(2)間接製作:SeqList *L;
L=(SeqList *)malloc(sizeof(SeqList));
考研中第二種考查的比較多。
void InitLinkList(ListNode *head)
{
if ((head=(LinkList)malloc(sizeof(ListNode)))==NULL)
{
exit(-1);
}
(head)->next = NULL;
cout << "分配成功" << endl;
}*/
//但是實際上使用最多的初始化方式是下面這種,以後樹的章節你還會見到。
void InitLinkList(LinkList *head)
{
if ((*head=(LinkList)malloc(sizeof(ListNode)))==NULL)
{
exit(-1);
}
(*head)->next = NULL;
cout << "分配成功" << endl;
}
bool IsLinkListEmpty(LinkList head)
{
if (head->next==NULL)
{
return true;
}
return false;
}
/*按照序號來查詢元素操作*/
//這裡需要注意的是返回的是i個位置的指標返回型別應該寫成ListNode *、
//大家也都知道ListNode *L=LinkList L;
//所以自然也可以這樣寫:LinkList Get(LinkList head, int i)
//兩者的效果是一樣的,親自動手一下就知道了。
//以下的函式返回時指標型別的同樣的解釋。
ListNode * Get(LinkList head, int i)
{
ListNode *p; int j=0;
if (IsLinkListEmpty(head))
{
return NULL;
}
else if(i<1){
return NULL;
}
else
{
p = head;
while (p->next!=NULL&&j<i)
{
p = p->next;
j++;
}
if (j==i)
{
return p;
}
else
{
return NULL;
}
}
}
/*查找節點值為e的節點並返回所對應的指標*/
ListNode *LocateElem(LinkList head, DataType e)
{
ListNode *p;
p = head->next;
while (p)
{
if (p->data!=e)
{
p = p->next;
}
else
{
break;
}
}
return p;
}
//通過元素值定位位置,缺點在於如果有兩個位置的資料值一樣,只能定位到前一個位置。
int LocatePosition(LinkList head, DataType e)
{
ListNode *p;
int i = 1;
if (IsLinkListEmpty(head))
{
return -1;
}
p = head->next;
while (p!=NULL)
{
if (p->data==e)
{
return i;
}
else
{
p = p->next;
i++;
}
}
if (p==NULL)
{
return -1;
}
else
{
return 1;
}
}
/*在i的位置插入元素,需要找到之前的i-1的指標*/
int InsertList(LinkList head, int i, DataType e)
{
ListNode *pre, *p;
pre = head;
int j = 0;
/*找到i-1個節點*/
while (pre->next!=NULL&&j<i-1)
{
pre = pre->next;
j++;
}
if (j!=i-1)
{
cout << "插入的節點位置有錯" << endl;
return -1;
}
if ((p=(ListNode*)malloc(sizeof(ListNode)))==NULL)
{
exit(-1);
}
p->data = e;
p->next = pre->next;
pre->next = p;
return 1;
}
//根據位置刪除掉單鏈表中的元素。
int DeleteList(LinkList head, int i, DataType * e)
{
ListNode *pre, *p;
int j = 0;
pre = head;
while (pre->next != NULL&&pre->next->next!=NULL&&j<i-1)
{
pre = pre->next;
j++;
}
if (j!=i-1)
{
cout << "刪除位置出錯" << endl;
return -1;
}
p = pre->next;
*e = p->data;
pre->next = p->next;
/*釋放P節點指向的點*/
free(p);
return 1;
}
//得到單鏈表的長度。
int ListLength(LinkList head)
{
LinkList p;
p = head;
int count = 0;
while (p->next!=NULL)
{
p = p->next;
count++;
}
return count;
}
//銷燬單聊表
void DestroyList(LinkList head)
{
ListNode *p,*q;
p = head;
while (p!=NULL)
{
q = p;
p = p->next;
free(q);
}
}
測試函式:
int main(){
cout << "測試開始"<<endl;
LinkList L;
InitLinkList(&L);
InsertList(L,1,'a');
cout << "單鏈表長度" << ListLength(L)<<endl;
LinkList getElumByNum;
getElumByNum = Get(L, 1);
cout <<"第一個位置元素是:"<< getElumByNum->data << endl;
DataType deleteElumValue;
DeleteList(L,1,&deleteElumValue);
cout << deleteElumValue << endl;
cout << "單鏈表長度" << ListLength(L) << endl;
system("PAUSE");
return 0;
}
執行結果: