線性表--順序表、單鏈表、雙鏈表 基礎操作總結
函數:
王道--數據結構--已在Visio Stdio 2019驗證成功!
順序表插入 刪除 查找
單鏈表的頭插法、尾插法,按值/按序查找,插入/刪除
雙鏈表的頭插法、尾插法,按值/按序查找,插入/刪除
驗證:
// 棧、隊列與順序表.cpp : 此文件包含 "main" 函數。
#include <iostream>
#include "stdio.h"
#define MaxSize 50
typedef int ElemType;
typedef struct {//靜態順序線性表定義
ElemType data[MaxSize];
int length;
}SqList;
typedef struct{//動態順序線性表定義
ElemType * data;
int seqlist_maxsize, Length;
}SeqList;
typedef struct LNode {//單鏈表定義
ElemType data;
struct LNode* next;
}*LinkList;
typedef struct DNode {//雙鏈表定義
ElemType data;
struct DNode *prior,*next;
}DNode,*DLinkList;
/************************順序線性表****************************/
//插入操作:在鏡頭順序表L的第i位置插入新元素e;
bool ListInsert(SqList* L, int i,ElemType e )
{
if (i<0 || i>L->length)
return false;
if (i > MaxSize)
return false;
for (int j = L->length; j >= i; j--)
L->data[j] = L->data[j-1];
L->data[i - 1] = e;
L->length++;
return true;
}
//刪除操作:刪除順序表中的第i個元素,刪除原始通過e返回
bool ListDelete(SqList &L,int i,ElemType *e)
{
if (i<0 || i>L.length)
return false;
if (i > MaxSize)
return false;
*e = L.data[i-1];
for (int j = i; j < L.length; j++)
L.data[j-1] = L.data[j];
L.length--;
return true;
}
//順序查找:按值查找
int LocateElem(SqList L, ElemType e)
{
for (int i = 0; i < L.length; i++)
{
if (L.data[i] == e)
return i + 1;
}
return 0;
}
/************************鏈式順序表****************************/
void PrintLink(LNode* head)
{
LNode* p = head->next;
for (; p; p = p->next)
printf("%5d", p->data);
}
//創建單鏈表1--頭插法
LinkList List_HeadInsert(LinkList &L)
{
LNode* s; int x;
L = (LinkList)malloc(sizeof(LNode));//創建頭節點
L->next = NULL; //初始爲空鏈表
printf("頭插法L輸入節點數據:");
scanf_s("%d",&x);
while (x!=999)
{
s = (LNode*)malloc(sizeof(LNode));//創建新節點
s->data = x;
s->next = L->next;
L->next = s;
scanf_s("%d", &x);
}
return L;
}
//創建單鏈表2--尾插法
LinkList List_TailInsert(LinkList &L)
{
LNode* s; int x;
L = (LinkList)malloc(sizeof(LNode));//
L->next = NULL; //初始爲空鏈表
LNode *r=L; //r爲附加設置的表尾指針
printf("\n尾插法L2輸入節點數據:");
scanf_s("%d", &x);
while (x != 999)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r=s; //r指向新的表尾結點
scanf_s("%d", &x);
}
r->next = NULL; //尾結點指針置空
return L;
}
//按序查找結點:查找單鏈表中第i個結點
LNode* GetElem(LinkList L,int i)
{
int j = 1;
LNode* p=L->next;//頭結點指針
if (i == 0)//0返回頭結點
return L;
if (i < 1)//無效返回空
return NULL;
while (p&&j < i)
{
p = p->next;
j++;
}
printf("\n按序查找結果:%d", p->data);
return p;
}
//按值查找結點:查找值爲e的元素並返回該指針
LNode* LocateElem(LinkList L, ElemType e)
{
LNode* p = L->next;
while (p && p->data != e)
p = p->next;
if (p == NULL)
printf("\n按值查找結果:無");
else
printf("\n按值查找結果:存在該元素");
return p;
}
//插入新結點
bool ListFrontInsert(LinkList L, int i, ElemType e)
{
LNode* p = L->next;
p = GetElem(L,i-1);
if (p == NULL) return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next=p->next;
p->next = s;
return true;
}
//刪除新結點
bool ListDelete(LinkList L, int i)
{
LNode* p = L->next;
p = GetElem(L, i - 1);
if (p == NULL) return false;
p->next= p->next->next;
return true;
//LNode* p = L->next;
//p = GetElem(L, i - 1);
//if (p == NULL) return false;
//LinkList q;
//q = p->next;
//p->next = q->next;
//free(q);
//return true;
}
/***********************雙指針鏈式順序表************************/
//創建雙鏈表1--頭插法
DLinkList Dlist_head_insert(DLinkList& DL) { //List_head_insert
DNode* s; int x;
DL = (DLinkList)malloc(sizeof(DNode));//建立頭結點
DL->next = NULL;
DL->prior = NULL;
printf("\n雙鏈表-輸入:");
scanf_s("%d", &x);
while (x != 999) {
s = (DNode*)malloc(sizeof(DNode));
s->data = x;
s->next = DL->next;
if (DL->next != NULL) {
DL->next->prior = s;
}
s->prior = DL;
DL->next = s;
scanf_s("%d", &x);
}
return DL;
}
//創建雙鏈表2--尾插法
DLinkList Dlist_tail_insert(DLinkList& DL) {//List_tail_insert
int x;
DL = (DLinkList)malloc(sizeof(DNode));
DNode* s, * r = DL;
DL->prior = NULL;
printf("\n雙鏈表-輸入:");
scanf_s("%d", &x);
while (x != 999) {
s = (DNode*)malloc(sizeof(DNode));
s->data = x;
r->next = s;
s->prior = r;
r = s;
scanf_s("%d", &x);
}
r->next = NULL;
return DL;
}
//按序查找結點:查找單鏈表中第i個結點
DNode* GetElem(DLinkList DL, int i) {
int j = 1;
DNode* p = DL->next;
if (i == 0)
return DL;
if (i < 1)
return NULL;
while (p && j < i) {
p = p->next;
j++;
}
return p;
}
//插入新結點
bool DListFrontInsert(DLinkList DL, int i, ElemType e) {
DLinkList p = GetElem(DL, i - 1);
if (NULL == p) {
return false;
}
DLinkList s = (DNode*)malloc(sizeof(DNode));
s->data = e;
s->next = p->next;
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
//刪除新結點
bool DListDelete(DLinkList DL, int i) {
DLinkList p = GetElem(DL, i - 1);
if (NULL == p) {
return false;
}
DLinkList q;
q = p->next;
if (q == NULL)
return false;
p->next = q->next;
if (q->next != NULL) { //刪除最後一個元素,需要的判斷
q->next->prior = p;
}
free(q);
return true;
}
//打印雙鏈表
void PrintDList(DLinkList DL) {
DL = DL->next;
while (DL != NULL) {
printf("%3d", DL->data);
DL = DL->next;
}
printf("\n");
}
//順序線性表
void Seq_List()
{
SqList L;
int data_buff;
for (int i = 0; i < 8; i++) { L.data[i] = i; L.length = i + 1; }
printf("\n插入前:");
for (int i = 0; i < L.length; i++) printf("%d\t", L.data[i]);
if (true == ListInsert(&L, 1, 9))
{
printf("\n插入後:");
for (int i = 0; i < L.length; i++) printf("%d\t", L.data[i]);
}
else
{
printf("\n插入 失敗!");
}
if (true == ListDelete(L, 1, &data_buff))
{
printf("\n刪除後:");
for (int i = 0; i < L.length; i++) printf("%d\t", L.data[i]);
}
else
{
printf("\n刪除失敗");
}
data_buff = LocateElem(L, 3);
if (data_buff == 0)
{
printf("\n查找失敗!");
}
else
{
printf("\n按值查找到元素位置爲%d!\n", data_buff);
}
}
//單鏈表的操作
void Link_List()
{
LNode* L,*head,*node,*L2;
bool statue=false;
//head = List_HeadInsert(L);//頭插建立
//PrintLink(head);
head = List_TailInsert(L2); //尾插建立
PrintLink(head);
node=GetElem(L2,1); //按序查找
node=LocateElem(L2,3); //按值查找
if (true == ListFrontInsert(L2,2,0))
{
printf("\n插入成功!插入結果:");
PrintLink(L2);
}
else
{
printf("\n插入失敗!結果:");
PrintLink(L2);
}
if (true == ListDelete(L2, 2))
{
printf("\n刪除成功!刪除結果:");
PrintLink(L2);
}
else
{
printf("\n刪除失敗!結果:");
PrintLink(L2);
}
}
//雙鏈表的操作
void DLink_List()
{
DNode *DL, * DL2,*dead;
ElemType buff;
dead = Dlist_head_insert(DL); //頭插法
PrintDList(DL);
dead = Dlist_tail_insert(DL2); //尾插法
PrintDList(DL2);
GetElem(DL2,1); //按序查找
if (true == DListFrontInsert(DL2, 2, 0)) //在i位插入
{
printf("\n雙鏈表插入成功!");
PrintDList(DL2);
}
else
{
printf("\n雙鏈表插入失敗!");
}
if (true == DListDelete(DL2, 2)) //在i位插入
{
printf("\n雙鏈表刪除成功!");
PrintDList(DL2);
}
else
{
printf("\n雙鏈表刪除失敗!");
}
}
int main()
{
std::cout << "Hello World!\n";
//Seq_List();//順序表插入 刪除 查找
//Link_List();//單鏈表的頭插法、尾插法,按值/按序查找,插入/刪除
DLink_List();//雙鏈表的頭插法、尾插法,按值/按序查找,插入/刪除
system("pause");
}