链表
- 数组
查找效率极高,插入删除效率很低 - 链表
查找效率极低,插入删除效率高
链表分类
单链表:有无头、是否循环
双链表:有无头、是否循环
- 单双链表,指的是否有指向前一个结点的指针(单链表只有指向后一个结点的指针)
- 有头无头,指的是链表头结点是否存储数据。
- 是否循环,指的是链表尾结点和头结点是否想连(尾结点的pNext等于头结点)
代码
- 无头不循环单链表
class Node
{
public:
int data;
Node* pNext;
Node(int NewData) :data(NewData) { pNext = NULL; }
};
class MyList
{
public:
Node* head;
MyList(Node node) //构造函数初始化链表头
{
Node* pNew = new Node(node.data);
head = pNew;
}
//往后插入
void push(Node node)
{
Node* pNew = new Node(node.data);
Node* temp = head;
while (temp->pNext)temp = temp->pNext;
temp->pNext = pNew;
}
//在某个位置插入数据(在找到的第一个相同的数的后面)
void insert(Node node, int finddata)
{
Node* temp = head;
while (temp)
{
if (finddata == temp->data)
{
break;
}
temp = temp->pNext;
}
if (!temp)
{
cout << "没找到这个位置" << endl;
return;
}
//连接
Node* pNew = new Node(node.data);
pNew->pNext = temp->pNext;
temp->pNext = pNew;
}
void delete_Data(int finddata)
{
Node* temp = head;
while (temp)
{
if (finddata == temp->pNext->data)
{
break;
}
temp = temp->pNext;
}
if (!temp)
{
cout << "没找到这个位置" << endl;
return;
}
Node* behindnode = temp->pNext->pNext;
delete temp->pNext;
temp->pNext = behindnode;
}
};
- 有头双链表循环
class MyList
{
public:
class Node
{
public:
int data;
Node* pNext;
Node* pPrev;
Node(int NewData) :data(NewData) { pNext = NULL; pPrev = NULL; }
Node() { data = -1; pNext = NULL; pPrev = NULL;}
};
Node* head;
MyList()
{
head = new Node;
head->pNext = NULL;
head->pPrev = NULL;
}
void push(int data)
{
//创建新节点
Node* newnode = new Node(data);
newnode->pNext = head;
Node* temp = head;
//假定是第一个有效节点,要和其它情况分开
if (head->pNext)
{
//找到最后那个节点
while (temp->pNext != head)temp = temp->pNext;
}
//完成连接工作
head->pPrev = newnode;
temp->pNext = newnode;
newnode->pPrev = temp;
}
};
这里简单的实现了链表的一部分功能,你完全可以采用不同的代码,不同的思想实现,完善更多功能。
有如下建议:
- 做更严格的权限限制,比如,给头结点private权限,提供接口来实现访问数据的功能。
- 更多的安全性检查,一个好的程序应该尽可能穷尽所有可能,当某种情况出现时做什么处理。
- 实现更多更细致的功能,比如,有后插也有前插,清空,遍历,从不同的位置开始遍历,遍历几个。。。等等
- 采用模板实现不同的数据类型管理,而不仅仅是int整型。
- 将所有涉及到的结构体,类,变量尽可能的放到同一个类中,达到更高的封装性,管理起来更方便。
- 提供更多有参构造(拷贝构造)或无参构造,以满足不同的需求。
- 增加更多的属性,比如,定义成员变量保存数据的数量。