代码写的比较水,为了解决超过表长的数据输进去发生的空指针问题,代码冗余太多了,但是基本功能都实现了。虽然我之前学过数据结构,但是其实跟没学过一样,算得上是重新学习了一遍。
-
代码
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct LNode{
int data;
struct LNode * next;
}*LinkList;
//求链表表长
int getLength(LinkList L){
LinkList p;
p = L->next;
int i = 1;
while(p){
i++;
p = p->next;
}
return i - 1;
}
//头插法建立单链表,也就是倒序输出,但是我更喜欢尾插法,因为他是按照顺序来的,
//所以这里只是把头插的方法写了出来,并没有调用
LinkList List_HeadInsert(LinkList &L){
LinkList s;
int x;
L = (LinkList)malloc (sizeof(struct LNode));
L->next = NULL;
cout << "请输入要插入的数据,输入-9999结束输入:";
cin >> x;
while(x != -9999){
s = (LinkList)malloc(sizeof (struct LNode));
s->data = x;
s->next = L->next;
L->next = s;
cin >> x;
}
return L;
}
//尾插法建立链表,即正序输出
LinkList List_TailInsert(LinkList &L){
int x;
L = (LinkList)malloc(sizeof(struct LNode));
LinkList cur,r = L;//这里面的r代表链表的尾结点,且必须始终保证他是尾结点,方便结点s接入链表
cout << "请输入要插入链表中的元素,输入-9999结束输入:";
cin >> x;
while(x != -9999){
cur = (LinkList)malloc(sizeof(struct LNode));
cur->data = x;
r->next = cur;
r = cur;
cin >> x;
}
r->next = NULL;
return L;
}
//按值查找返回对应序号位置(链表中没有重复的元素)
int byValue_getIndex(LinkList L,int e){
int num = 1;
LinkList p;
p = L->next;
while((p->data != e) && (p != NULL)){
num++;
if(p->next != NULL)
p = p->next;
else
return 0;
}
return num;
}
//按位置查找对应元素值
LinkList byIndex_getValue(LinkList L,int n){
int length = getLength(L);
//cout << length;
int i = 1;
if(n < 1 || n > length){
cout << "您输入的数据不合法,超过表长或者小于1:" << endl;
return NULL;
}else{
LinkList p;
p = L->next;
//这里如果不先判断n跟表长length的关系会出现空指针异常,也就是当你输入一个超过表长的数据的时候
while(p && (i < n)){
p = p->next;
i++;
}
return p;
}
}
//按照给定位置后插结点
LinkList byIndex_behindInsert(LinkList L,int j,int x){
LinkList p = byIndex_getValue(L,j);
if(p != NULL){
LinkList s;
s = (LinkList)malloc(sizeof(struct LNode));
s->data = x;
s->next = p->next;
p->next = s;
return L;
}else return NULL;
}
//按给定位置前插结点
LinkList byIndex_beforeInsert(LinkList L,int j,int x){
int temp;
if(j == 1){
LinkList s;
s = (LinkList)malloc(sizeof(struct LNode));
s->data = x;
s->next = L->next;
L->next = s;
return L;
}else{
LinkList p = byIndex_getValue(L,j);
if(p != NULL){
LinkList s;
s = (LinkList)malloc(sizeof(struct LNode));
s->data = x;
s->next = p->next;
p->next = s;
temp = s->data;
s->data = p->data;
p->data = temp;
return L;
}else return NULL;
}
}
//按值删除结点(假设表中没有重复结点)
LinkList deleteNode(LinkList L,int x){
LinkList p;
LinkList q = L;
p = L->next;
while(p->data != x){
if(p->next == NULL){
cout << "查找失败,链表中没有对应元素" << endl;
return NULL;
}else{
p = p->next;
q = q->next;
}
}
q->next = p->next;
free(p);
return L;
}
//按位置删除结点
LinkList deleteNode_index(LinkList L,int n){
if(n < 1){
cout << "您输入的数据不合法,请输入一个大于1的数!" << endl;
return NULL;
}
int i = 1;
LinkList p,q;
q = L;
p = L->next;
while(p != NULL && i < n){
if(p->next != NULL){
p = p->next;
i++;
q = q->next;
}else{
cout << "您输入的数据不合法,已经超过表长范围!" << endl;
return NULL;
}
}
cout << "您删除的结点是:" << p->data << endl;
q->next = p->next;
free(p);
return L;
}
//按位置更改元素
LinkList byLocation_changeValue(LinkList L,int n,int e){
if(n < 1){
cout << "您输入的数据不合法,请输入一个大于1的数!" << endl;
return NULL;
}
int i = 1;
LinkList p;
p = L->next;
while(i < n && p != NULL){
if(p->next != NULL){
p = p->next;
i++;
}else{
cout << "您输入的数据不合法,输入的数据已经大于表长!" << endl;
return NULL;
}
}
p->data = e;
return L;
}
//按值更改元素
LinkList byValue_changeValue(LinkList L,int e,int changeE){
LinkList p;
p = L->next;
while(p->data != e){
if(p->next != NULL) p = p->next;
else {
cout << "您要更改的值在链表中不存在!" << endl;
return NULL;
}
}
p->data = changeE;
return L;
}
//打印链表
void print(LinkList L){
LinkList p = L->next;
while(p != NULL){
int x = p->data;
cout << x << " ";
p = p->next;
}
cout << endl;
}
int main()
{
LinkList L;
LinkList b;
int sel;
int byValue_search;
int getIndex;
int small_sel;
int search_index;
int behindInsertIndex,behindInsertValue;
int beforeInsertIndex,beforeInsertValue;
int deleteValue;
int deleteIndex;
int changeIndex,index_changeValue;
int primerValue,value_choiceValue;
cout << "功能如下:"<< endl;
cout << "--------1.尾插法建立链表--------" << endl;
cout << "--------2.打印链表--------" << endl;
cout << "--------3.按值查找元素,返回位置序号--------" << endl;
cout << "--------4.按位置查找元素,返回值--------" << endl;
cout << "--------5.按位置后插元素--------" << endl;
cout << "--------6.按位置前插元素--------" << endl;
cout << "--------7.按值删除结点--------" << endl;
cout << "--------8.按位置删除结点--------" << endl;
cout << "--------9.按位置更改元素--------" << endl;
cout << "--------10.按值更改元素--------" << endl;
while(true){
cout << "请输入选择的功能:";
cin >> sel;
switch(sel){
case 1:
List_TailInsert(L);
break;
case 2:
print(L);
break;
case 3:
cout << "请输入要查找的值:";
cin >> byValue_search;
getIndex = byValue_getIndex(L,byValue_search);
if(getIndex == 0){
cout << "您要查找的值不在链表内!" << endl;
}else{
cout << "值" << byValue_search << "在第" << getIndex << "位" << endl;
}
break;
case 4:
cout << "请输入要查找的位置索引:";
cin >> search_index;
b = byIndex_getValue(L,search_index);
if(b)
cout << search_index << "位置对应的元素为:" << b->data <<endl;
break;
case 5:
cout << "请输入要插入元素的位置和插入的元素:";
cin >> behindInsertIndex;
cin >> behindInsertValue;
byIndex_behindInsert(L,behindInsertIndex,behindInsertValue);
break;
case 6:
cout << "请输入要插入元素的位置和插入的元素:";
cin >> beforeInsertIndex;
cin >> beforeInsertValue;
byIndex_beforeInsert(L,beforeInsertIndex,beforeInsertValue);
break;
case 7:
cout <<"请输入要删除结点的值:";
cin >> deleteValue;
deleteNode(L,deleteValue);
break;
case 8:
cout << "请输入要删除结点的位置:";
cin >> deleteIndex;
deleteNode_index(L,deleteIndex);
break;
case 9:
cout << "请输入您要更改的位置和元素:";
cin >> changeIndex >> index_changeValue;
byLocation_changeValue(L,changeIndex,index_changeValue);
break;
case 10:
cout << "请输入原本的值,和您想要更改的值:";
cin >> primerValue >> value_choiceValue;
byValue_changeValue(L,primerValue,value_choiceValue);
break;
}
}
return 0;
}